Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matching arrays in elastic search

I have document as below:

{
    "_index": "abc_local",
    "_type": "users",
    "_id": "1",
    "_version": 5,
    "found": true,
    "_source": {
        "firstname": "simer",
        "lastname": "kaur",
        "gender": "1",
        "Address": "Punjab House Fed. Housing Society, Amritsar, Punjab, India",
        "email": "[email protected]",
        "occupation": "Php Developer",
        "work": "Development",
        "fav_hunting_land": 2,
        "zipcode": "",
        "marital_status": "1",
        "phone": "1234567899",
        "school": "sdfergdfh",
        "species": [{
            "id": 1
        }, {
            "id": 2
        }, {
            "id": 3
        }, {
            "id": 4
        }, {
            "id": 5
        }, {
            "id": 6
        }],
        "activities": [{
            "id": 1
        }],
        "fav_weapon": 6,
        "weapons": [{
            "id": 1
        }, {
            "id": 2
        }, {
            "id": 3
        }, {
            "id": 6
        }],
        "properties": [{
            "id": 4
        }]
    }
}

and I need to match user on basis of weapons and I am trying something like:

$params = [
            'index' => Constants::INDEX,
            'type' => Constants::DOC_TYPE_USERS,
            'body' => [
                "query"=> [
                    "bool"=> [
                        "must"=>   [ "match"=> [ "weapons.id"=>$params['weapons'] ]],

                        "should"=> [
                                    [ "match"=> [ "firstname"=> $params['search_text'] ]],
                                    [ "match"=> [ "lastname"=> $params['search_text']   ]]
                                        ]
                                    ]
                            ]
                        ]

                ];

as I am using elastic in PHP. Here $params['weapons'] is:

array (size=2)
  0 => string '1' (length=1)
  1 => string '2' (length=1)

I get an error:

illegal_state_exception: Can't get text on a START_ARRAY at 1:36

Any suggestions/help would be appreciated that how I can match array. I took reference from nested datatypes

Update#1: parameters I am sending to my function: {"from":0,"size":null,"city":null,"state":"0","weapons":["1","2"],"activities":[],"species":[],"properties":[],"search_text":"lastname"}

update#2: Body of my query in json format:

{
    "index": "abc_local",
    "type": "users",
    "body": {
        "query": {
            "bool": {
                "must": {
                    "match": {
                        "weapons.id": ["1", "2"]
                    }
                },
                "should": [{
                    "match": {
                        "firstname": "simer"
                    }
                }, {
                    "match": {
                        "lastname": "simer"
                    }
                }]
            }
        }
    }
}
like image 337
Always_a_learner Avatar asked Nov 22 '16 06:11

Always_a_learner


People also ask

What is Elasticsearch matching?

The match query is of type boolean . It means that the text provided is analyzed and the analysis process constructs a boolean query from the provided text. The operator parameter can be set to or or and to control the boolean clauses (defaults to or ).

What is the difference between term and match in Elasticsearch?

To better search text fields, the match query also analyzes your provided search term before performing a search. This means the match query can search text fields for analyzed tokens rather than an exact term. The term query does not analyze the search term. The term query only searches for the exact term you provide.

What is the difference between must and should in Elasticsearch?

must means: Clauses that must match for the document to be included. should means: If these clauses match, they increase the _score ; otherwise, they have no effect. They are simply used to refine the relevance score for each document. Yes you can use multiple filters inside must .

How do I write a script in Elasticsearch?

Wherever scripting is supported in the Elasticsearch APIs, the syntax follows the same pattern; you specify the language of your script, provide the script logic (or source), and add parameters that are passed into the script: "script": { "lang": "...", "source" | "id": "...", "params": { ... } }


1 Answers

You can simply replace the first match query by a terms one as match doesn't work with arrays of values.

 $params = [
        'index' => Constants::INDEX,
        'type' => Constants::DOC_TYPE_USERS,
        'body' => [
            "query"=> [
                "bool"=> [
                    "must"=>   [ "terms"=> [ "weapons.id"=>$params['weapons'] ]],
                                    ^
                                    |
                               change this

                    "should"=> [
                                [ "match"=> [ "firstname"=> $params['search_text'] ]],
                                [ "match"=> [ "lastname"=> $params['search_text']   ]]
                                    ]
                                ]
                        ]
                    ]

            ];
like image 99
Val Avatar answered Sep 28 '22 19:09

Val