Node.js from Getting started to combat (eight) SOLR hierarchy __js

Source: Internet
Author: User
Tags export class solr solr query

Reference: Node.js from entry to combat (vii) The summary of the SOLR query rules

Reference: SOLR Search Service Architecture Diagram I, SOLR hierarchy

SOLR as a key search component, the architecture throughout the system is shown in the following illustration:

SOLR's Indexing Service is designed to improve search efficiency, and, in general, SOLR needs to work with NoSQL DB as a separate complement to NoSQL DB, while maintaining a higher indexing efficiency when it is able to enjoy the advantages of NoSQL db (such as storage traversal, speed, and so on).

SOLR is generally used in the use of encapsulated services in the style of use, the online presence of an architectural diagram below (see reference):

solr resolves the fields in the URL as a service and follows the SOLR query rules, so how to build the query substring into the SOLR-defined style is key to SOLR's use.

In general, if you publish SOLR as a component to the remaining subsystems within the system, SOLR should have the parse built-in functionality to convert a normal query into a SOLR query string, which reduces the complexity of use for the caller of the SOLR service. For the interior of SOLR, it is also helpful for parameter checking and control. Two, SOLR asynchronous packaging

SOLR's process of operation is synchronized blocking, this process will increase the delay and uncertainty of the system, the implementation of asynchronous call is to improve stability, reduce the difficulty of coding an effective way, and in the Node.js+react architecture, The use of Promise encapsulation solr-client can achieve asynchronous purposes.
2.1 Promise

The Promise object is used to represent the final state (completion or failure) of an asynchronous operation and the value it returns . The Promise object is a proxy object (the proxy is a value), and the value of the proxy may be unknown when the Promise object is created. It allows you to bind the corresponding processing method (handlers) separately for the success and failure of the asynchronous operation. This allows the asynchronous method to return a value like a synchronous method , but not immediately returns the final execution result, but rather a promise object that represents future results .
A promise has several states:
Pending: Initial state, neither a success nor a failure state. Fulfilled: means the operation completed successfully. Rejected: means the operation failed. The Promise object of the pending state can trigger a fulfilled state and pass a value to the appropriate state-processing method, or it may trigger a failed state (rejected) and pass the failure message . When either of these cases occurs, the then method binding ( handlers ) of the Promise object is invoked (the then method contains two parameters: onfulfilled and onrejected , they are all Function types . When the promise State is fulfilled, the then onfulfilled method is invoked, and the Promise method is invoked when the rejected state is then, so the There is no competition between the completion and the binding processing method .

The Promise object is created by the keyword new and its constructors. The constructor takes a function called a " processor function " (executor functions) as its argument. This "processor function" accepts two functions--resolve and reject --as its arguments. The resolve function is called when the asynchronous task completes successfully and the result value is returned, and the Reject function is invoked when the asynchronous task fails and returns the reason for failure (usually an Error object). Want a function? have the Promise function, just let it return to a promise.

function myasyncfunction (URL) {return
  new Promise (Resolve, Reject) => {
    const XHR = new XMLHttpRequest (); ("get", url);
    Xhr.onload = () => resolve (xhr.responsetext);
    Xhr.onerror = () => reject (xhr.statustext);
    Xhr.send ();

2.2 Server-side SOLR encapsulation

Server-side SOLR encapsulates the search method provided by the Solr-client access Solr,solr-client as a synchronization method, which is encapsulated as follows:

Import SOLR from ' solr-client ';

Const SOLRHOST = ""
const Solrport = "8393"
Export class Solrsearcher {

  Constructor (core:string) {
    this.client = solr.createclient ({
      Core: Core,
  Search<t> (Conditions:object, Mapper: (doc:object) => T): promise<asyncresult<t>> {return
    This.asyncsearch (This.buildurl (conditions), mapper);
In Solrsearcher, the search method is encapsulated, the parameter is set as the Map object, and the parameters are processed within the package search to generate the URL string used by the query. AsyncsearchMethod in:

Asyncsearch<t> (Query:any, Mapper: (doc:object) => T): promise<asyncresult<t>> {return
    new Promise ((Resolve, Reject) => { (query, err, obj) => {
        if (err) {
          reject (err);
        } else {
          if (obj.responseHeader.status = 0) {
            resolve ({
     (Doc => Mapper ( doc)),
          else {
            reject (new Error (' asyncsearch status is not 0. ');}}});}
Results returned in this package asyncresultContains the returned data map and the number of results returned.

This completes the service-side solr-client encapsulation (where the buildurl needs to be processed according to the format of the incoming map). Iii. Services provided by SOLR

The question to consider after completing the server-side package is how the Solrsearcher is used.

As a search service, SOLR provides search services in a Solr-cloud cluster in a complex and highly available scenario, while Solr-client encapsulation is an application-level encapsulation, and the concept of micro-service should be viewed as a service, built on Solr-cloud, It is used as a back-end data query interface while shielding and encapsulating the Solr-cloud. Here you also need to introduce a query standard GRAPHQL that defines the format for querying and returning results. (see Node.js from Getting Started to combat (ix) GRAPHQL integration with SOLR).

According to the business segmentation, false with score and rank two use scenarios need to use Solr-client, based on DDD can create the following structure:

|---config/		#放置系统配置: such as IP, port number
|---domains/		#DDD主文件夹
    |---score/		#score下的
        |--- Index.js      #提供export声明
        |---model.js      #模型定义
        |---repository.js #提供公用service模块
        |---service.js    #定义专用service
        ---index.js      #提供export声明
        |---model.js      #模型定义
        |--- Repository.js #提供公用service模块
        |---service.js    #定义专用service
        |--- Solrsearcher  #异步SolrClient
index.js                  #主要入口, create Express app and GRAPHQL rule, bind schema
schema.js                 #定义graphql使用的定义 (including all model/repository/service), bind query and resolver
query.js                  #绑定所有的model, And the service is declared, binding
resolver.js               #绑定所有的service
In the Nineth article graphql and SOLR in the combination of a detailed analysis. As you can see in the table above, solrsearcher as an internal component of Microservice, providing a query interface to SOLR. iv. Format of SOLR query statements

According to the seventh SOLR query rule, the incoming string should also match the SOLR rule as a micro-service on top of SOLR. The calling interface of the encapsulated asynchronous Solrsearch is as follows:

  Search<t> (Conditions:object, Mapper: (doc:object) => T): promise<asyncresult<t>> {return
    This.asyncsearch (This.buildurl (conditions), mapper);
That is, the first entry in the search interface is JSONObject conditionsUse BuildUrl functionConverted to a string that SOLR could recognize after processing,

The second entry is the function body Mapper, which provides a method for constructing the return value type of a JSON string (or XML document, which is a return value of SOLR) into a search function , used to Assists the Asyncsearch function to construct the return value , whose entry parameter is (Doc:object), and the return value is the return value <T> that the query expects. 4.1 buildurl

The BuildUrl method is used to process the input JSON object and generate a URL string that SOLR can recognize, one example is as follows:

BuildUrl (conditions:object) {
    const q = CONDITIONS.Q | | '*:*';

    This.queryescape (q);           /* Processing SOLR Escape Special Characters
    /Const query = This.client
      . CreateQuery ()                
      . Q (q)/                        * Main query Parameters
      * *. Sort (conditions.sort)/       * Introduce a sorting method */
      . Start (Conditions.start)/     * Introduce the starting serial number
      /. Rows (conditions.rows)       * * Introduction of the total number of queries
      /* EDISMAX ()/                   * Introduce weight ordering
      /QF (CONDITIONS.QF);          /* Introduce query field * *

    const FQ = CONDITIONS.FQ | | {};  * * Introduction of filtration conditions
    /this._queryescape (FQ);           /* Process SOLR Escape Special Characters * *
    (let K-Fq) {/              * to introduce FQ
      /Query.matchfilter (k, fq[k] one by one);
    } ( ());
    return query;
Where Queryescape is used to process special characters, including: +-&& | |! ( ) { } [ ] ^ " ~ * ? : /), the filtering method is very simple, with \ for escaping
  Queryescape (Q:object | string): void {
    if (typeof q!== ' string ') {for
      (let key of Object.keys (q)) {
        if (typ EOF Q[key] = = = = ' String ') {
          Q[key] = ' ${q[key]} '}}
The use of template strings makes it easy to escape special characters.
4.2 Mapper

The mapper function is used to process the return result, and its invocation is in the Resolve function:

if (Obj.responseHeader.status = = 0) {
  resolve ({ (Doc => mapper (DOC)),
else {
  logger.error (obj);
  Reject (New Error (' Response status is not 0. ');
The mapper function needs to vary according to the structure of the returned object, primarily by populating the JSON string into the object's location for the following definition:

  School: Schoola
  linechart: {}

You can write the following mapper function:

Scoremapper (doc:object): Score {
  if (doc.linchart) {
    Doc.linechart = (Image => Json.parse (image));
  Const TEACHER = Json.parse (doc.teacher);
  Const Subjectscore = json.parse (Doc.score | | '{}');
  Const SUBJECTID = Subjectscore.subjectid | | {};
  Const SUBJECTNAME = Subjectscore.subjectname | | {};
  Const SCORE = Subjectscore.score | | {};
  Const Scoreinstance = {,,};
  return new Score (scoreinstance);

By passing this mapper in, you can convert the JSON object obtained by the query to a score object.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.