在嵌套的elasticsearch对象中的所有键内搜索值

时间:2017-03-25 17:29:58

标签: php elasticsearch

我想知道是否可以在一个查询中搜索嵌套Elasticsearch对象中所有数组元素的值?请看下一个我的情况:

ElasticSearch数据库中,我在列name上配置了一个嵌套对象:

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

然后我插入以下数据(通过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',
    ]
);

然后我使用POST方法通过Postman Chrome扩展程序查询此数据:

POST http://localhost:9200/_search

身体是:

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

这很完美。在上面的查询中 - 我根据English列中的name翻译查询数据。

因此,如果我想使用Russian语言进行搜索,那么代码就是:

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

现在,我想要做的是同时查询所有翻译(可以提供1到100种语言)。类似的东西:

{ "match": { "name.*": "First" }}
  1. 问题 - 是可能的,使用我当前的配置?如果没有当前配置,那怎么样?我知道如果我将name列转换回普通类型(而不是nested) - 那么就有可能,因为所有翻译都集中在一个string类型的值中。但在那种情况下 - 我失去了选择性的可能性!我想要两个:) 最好不要重复数据

  2. 问题 - 如果我同时搜索所有翻译 - 是否可以优先考虑一种语言而不是另一种语言?因此,如果单词data包含5种语言 - 我希望包含English搜索结果的文档在列表中排在第一位。

1 个答案:

答案 0 :(得分:0)

好的,

经过无数教程后,我得出结论ElasticSearch无法与Associative arrays一起使用。相反 - 应使用Multidimensional arrays

这是一个例子。之前:

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

转换为多维:

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

现在,回到我的问题。结束ElasticSearch查询如下所示:

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

                }
            }
        }
    }
}

数目:

  • 回答问题1 - 从上面的查询中移除should部分。

  • 回答问题2 - 保留should部分。在那里设置首选语言代码。

如果我们想按特定语言进行搜索,则应将should设置为must