0

I want to know if it is possible to search value in all array elements in a nested Elasticsearch object in one single query? See my situation next:

In ElasticSearch database I've configured a nested object on column name:

$set_index = [
    'index' => 'table',
    'body' => [
        'mappings' => [
            'table' => [
                '_source' => [
                    'enabled' => true
                ],
                'properties' => [
                    "name" => [ // name of column
                        "type" => "nested" 
                    ],
                ]
            ]
        ]
    ]
];

Then I insert following data (through PHP):

$data1 = array(
    'descripotion' => 'Row 1',
    'name' => [
        'en' => 'First name data',
        'ru' => 'Первое имя',
        'de' => 'Eins data',
        'it' => 'something else',
    ]
);

$data2 = array(
    'descripotion' => 'Row 2',
    'name' => [
        'en' => 'Second name data',
    ]
);

And then I query on this data using the POST method through Postman Chrome extension:

POST http://localhost:9200/_search

Body is:

{
    "query":{
        "nested": {
            "path": "name",
            "query": {
                "bool": {
                    "must": [
                            { "match": { "name.en": "First" }}
                    ]
                }
            }
        }
    }
}

This is working perfectly. In above query - I am querying data based on English translation in column name.

So if I wanted to search using the Russian language, the code would have been following:

{ "match": { "name.ru": "First" }}

Now, what I want to do - is to query on all translations at the same time (there can be 1 to 100 languages provided). Something like:

{ "match": { "name.*": "First" }}
  1. question - is That possible, using my current config? If not with current config, then how? I know that if I convert name column back to normal type (instead of nested) - then it becomes possible, as all translations are concentrated into a single string type value. But in that case - i am loosing the possibility to be selective! I want both :) Preferably, without data duplication.

  2. question - if I am searching for all translations at the same time - is it possible to prioritize one language over another? So if word data is in 5 languages - I want the document which contained English search result - to be first in the list.

1 Answer 1

1

Alright,

After going through countless tutorials I have come to the conclusion that ElasticSearch can not work with Associative arrays. Instead - Multidimensional arrays shall be used.

Here is an example. Before:

$arr = array(
    'name' => [
        'en' => 'First name',
        'ru' => 'Первое имя',
    ]
);

Converted to multidimensional:

$arr = array(
    'name' => [ 
        [
            'lang' => 'en',
            'value' => 'First name data'
        ],
        [
            'lang' => 'ru',
            'value' => 'Первое имя'
        ]
    ]
);

Now, back to my questions. Ending ElasticSearch query looks like this:

{
    "query":{
        "nested": {
            "path": "name",
            "query": {
                "bool": {
                    "should": [
                            { "term": { "name.lang": "it" }}
                    ],
                    "must": [
                            { "match": { "name.value": "first" }}
                    ]

                }
            }
        }
    }
}

Answers:

  • Answer to question 1 - remove should section from query above.

  • Answer to question 2 - keep the should section. Set the preferred language code there.

And if we want to search by specific language then should should be set to must.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.