Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A simple AND query with Elasticsearch

I am trying to do a simple query for two specified fields, and the manual and google is proving to be of little help. Example below should make it pretty clear what I want to do.

{
  "query": {
      "and": {
        "term": {
          "name.family_name": "daniel",
          "name.given_name": "tyrone"
        }
      }
   }
}

As a bonus question, why does it find "Daniel Tyrone" with "daniel", but NOT if I search for "Daniel". It behaves like a realy weird anti case sensitive search.

like image 985
Alexander Morland Avatar asked Mar 18 '13 12:03

Alexander Morland


People also ask

What is Elasticsearch query?

In Elasticsearch, searching is carried out by using query based on JSON. A query is made up of two clauses − Leaf Query Clauses − These clauses are match, term or range, which look for a specific value in specific field.

How do you query elastic data?

You can use the search API to search and aggregate data stored in Elasticsearch data streams or indices. The API's query request body parameter accepts queries written in Query DSL. The following request searches my-index-000001 using a match query. This query matches documents with a user.id value of kimchy .

Can you query Elasticsearch with SQL?

Scalable search with scoring ... and SQLWith Elasticsearch SQL, you can access that full text search, blazing speed, and effortless scalability with a familiar query syntax.


2 Answers

Edit: Updated, sorry. You need a separate Term object for each field, inside of a Bool query:

{
  "query": {
    "bool": {
        "must" : [
          {
           "term": {
             "name.family_name": "daniel"
           }
         },
         {
           "term": {
             "name.given_name": "tyrone"
           }
         }
       ]
     }
   }
}

Term queries are not analyzed by ElasticSearch, which makes them case sensitive. A Term query says to ES "look for this exact token inside your index, including case and punctuation".

If you want case insensitivity, you could add a keyword + lowercase filter to your analyzer. Alternatively, you could use a query that analyzes your text at query time (like a Match query)

Edit2: You could also use And or Bool filters too.

like image 171
Zach Avatar answered Sep 21 '22 10:09

Zach


I found a solution for at least multiple text comparisons on the same field:

{
  "query": {
    "match": {
      "name.given_name": {
        "query": "daniel tyrone",
        "operator": "and"
      }
    }
  }

And I found this for multiple fields, is this the correct way?

{
  "query": {
    "bool": {
      "must": [        
        {
          "match": {
            "name.formatted": {
              "query": "daniel tyrone",
              "operator": "and"
            }
          }
        },
        {
          "match": {
            "display_name": "tyrone"
          }
        }
      ]
    }
  }
}
like image 30
Alexander Morland Avatar answered Sep 20 '22 10:09

Alexander Morland