Matching arrays in elastic search

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”: “rav@yopmail.com”,
“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”
}
}]
}
}
}
}

Solutions/Answers:

Solution 1:

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']   ]]
                                    ]
                                ]
                        ]
                    ]

            ];

Solution 2:

if u want to check if any value from array matches to field from index then you have to “terms” instead of match.

{
    "index": "abc_local",
    "type": "users",
    "body": {
        "query": {
            "bool": {
                "must": {
                    "terms": {
                        "weapons.id": ["1", "2"]
                    }
                },
                "should": [{
                    "match": {
                        "firstname": "simer"
                    }
                }, {
                    "match": {
                        "lastname": "simer"
                    }
                }]
            }
        }
    }
}

refer “Terms Level Query” in ElasticSearch docs.

Related:  Switching between the nodes in ElasticSearch using JEST client

References