Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use ElasticSearch Query params (DSL query) for multiple types?

I have been working with the ElasticSearch from last few months, but still find it complicated when I have to pass an complicated query.

I want to run the query which will have to search the multiple "types" and each type has to be searched with its own "filters", but need to have combined "searched results"

For example:

I need to search the "user type" document which are my friends and on the same time i have to search the "object type" document which I like, according to the keyword provided.

OR

The query that has both the "AND" and "NOT" clause

Example query:

$options['query'] = array(
        'query' => array(
            'filtered' => array(
                'query' => array(
                    'query_string' => array(
                        'default_field' => 'name',
                        'query' => $this->search_term . '*',
                    ),
                ),
                'filter' => array(
                    'and' => array(
                        array(
                            'term' => array(
                                'access_id' => 2,
                            ),
                        ),
                    ),

                    'not' => array(
                        array(
                            'term' => array(
                                'follower' => 32,
                            ),
                        ),

                        array(
                            'term' => array(
                                'fan' => 36,
                            ),
                        ),
                    ),
                ),
            ),
        ),
    );

as this query is meant to search the user with access_id = 2, but must not have the follower of id 32 and fan of id 36

but this is not working..

Edit: Modified query

{
  "query": {
    "filtered": {
      "filter": {
        "and": [
          {
            "not": {
              "filter": {
                "and": [
                  {
                    "query": {
                      "query_string": {
                        "default_field": "fan",
                        "query": "*510*"
                      }
                    }
                  },
                  {
                    "query": {
                      "query_string": {
                        "default_field": "follower",
                        "query": "*510*"
                      }
                    }
                  }
                ]
              }
            }
          },
          {
            "term": {
              "access_id": 2
            }
          }
        ]
      },
      "query": {
        "field": {
          "name": "xyz*"
        }
      }
    }
  }
}

now after running this query, i am getting two results, one with follower: "34,518" & fan: "510" and second with fan:"34", but isn't it supposed to be only the second one in the result.

Any ideas?

like image 792
Chetan Sharma Avatar asked Aug 25 '11 17:08

Chetan Sharma


People also ask

What is multi match query in Elasticsearch?

The multi_match query provides a convenient shorthand way of running the same query against multiple fields.

How do I merge two queries in Elasticsearch?

You need to use the bool query to combine different queries together. You can then choose whether each single query must match, should match (optional), or must not match.

For what purpose is query DSL used in Elasticsearch?

Query DSLedit. Elasticsearch provides a full Query DSL (Domain Specific Language) based on JSON to define queries. Think of the Query DSL as an AST (Abstract Syntax Tree) of queries, consisting of two types of clauses: Leaf query clauses.

What is DSL query?

Query DSL stands for Domain Specific Language. In elasticsearch, searching is performed using the search query, which is based on JSON. Elasticsearch provides full query DSL that helps to define queries. There are two clauses in elasticsearch that make a query, which are - 1.


2 Answers

You may want to look at the slides of a presentation that I gave this month, which explains the basics of how the query DSL works:

Terms of endearment - the ElasticSearch Query DSL explained

The problem with your query is that your filters are nested incorrectly. The and and not filters are at the same level, but the not filter should be under and:

curl -XGET 'http://127.0.0.1:9200/_all/_search?pretty=1'  -d '
{
   "query" : {
      "filtered" : {
         "filter" : {
            "and" : [
               {
                  "not" : {
                     "filter" : {
                        "and" : [
                           {
                              "term" : {
                                 "fan" : 36
                              }
                           },
                           {
                              "term" : {
                                 "follower" : 32
                              }
                           }
                        ]
                     }
                  }
               },
               {
                  "term" : {
                     "access_id" : 2
                  }
               }
            ]
         },
         "query" : {
            "field" : {
               "name" : "keywords to search"
            }
         }
      }
   }
}
'
like image 54
DrTech Avatar answered Sep 18 '22 09:09

DrTech


I just tried it with the "BOOL"

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "access_id": 2
          }
        },
        {
          "wildcard": {
            "name": "xyz*"
          }
        }
      ],
      "must_not": [
        {
          "wildcard": {
            "follower": "*510*"
          }
        },
        {
          "wildcard": {
            "fan": "*510*"
          }
        }
      ]
    }
  }
}

It gives the correct answer.

but I'm not sure should it be used like this ?

like image 37
Chetan Sharma Avatar answered Sep 20 '22 09:09

Chetan Sharma