This is my 14th day of The August Update Challenge

Test data:

POST /cross_fileds_test/_doc/1
{
  "last_name": "Will",
  "first_name": "Smith"
}


POST /cross_fileds_test/_doc/2
{
  "last_name": "Smith",
  "first_name": "Will"
}

POST /cross_fileds_test/_doc/3
{
  "last_name": "John",
  "first_name": "Smith"
}


POST /cross_fileds_test/_doc/4
{
  "last_name": "Smith",
  "first_name": "John"
}
Copy the code

Suppose we want to find the document that contains Will Smith, if we use best_fields to query, then specify that both words must be included, operator=and:

GET /cross_fileds_test/_search
{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "best_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator":   "and" 
    }
  }
}
Copy the code

But best_fields is field-centric, meaning that the operator parameter will be applied independently to each field. The above query would look like this:

(first_name:will AND first_name: smith) OR (last_name:will AND last_name:smith)
Copy the code

Return data:

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}
Copy the code

This will result in a requirement that all participles appear in the same field at the same time, requiring either will simth to appear in first_name or will simth to appear in last_name. It is clear that the first_name and last_name queries do not meet the requirements.

So, how can we meet our needs? Cross_fileds is a good fit for our query requirements. Cross_field: Finds each participle in any field. Use participle – centered. It first parses the query string into individual participles and then looks for each participle in any field as if they were one large field.

Continue searching to find the document containing Will Smith:

GET /cross_fileds_test/_search
{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "cross_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator":   "and" 
    }
  }
}
Copy the code

The specific process of the above query:

  1. Parse the query string into separate participles: Will and Smith;
  2. Then look for each participle in any field: (first_name:will OR last_name:will) AND (first_name: Smith OR last_name: Smith)

This means that all participles must appear in at least one field to match the document. So the above query will find documents in two cases:

  1. Either first_name is will and last_name is Smith;
  2. Either first_name is Smith and last_name is Will.

Only doc1 and doc2 satisfy the requirement:

{ "took" : 6, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : {" total ": {" value" : 2, the "base" : "eq"}, "max_score" : 1.89712, "hits" : [{" _index ": "Cross_fileds_test _type", "" :" _doc ", "_id" : "1", "_score" : 1.89712, "_source" : {" last_name ": "Will", "first_name" : "Smith" } }, { "_index" : "cross_fileds_test", "_type" : "_doc", "_id" : "2", "_score" : 1.89712, the "_source" : {" last_name ":" Smith ", "first_name" : "Will"}}}}]Copy the code