【问题标题】:Matching arrays in elastic search弹性搜索中的匹配数组
【发布时间】:2019-05-22 19:40:11
【问题描述】:

我有如下文件:

{
    "_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
        }]
    }
}

我需要根据武器匹配用户,我正在尝试类似:

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

                ];

因为我在 PHP 中使用弹性。这里的 $params['weapons'] 是:

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

我收到一个错误:

illegal_state_exception:无法在 1:36 的 START_ARRAY 上获取文本

任何建议/帮助将不胜感激我如何匹配数组。我参考了nested datatypes

更新#1: 我发送给我的函数的参数:{"from":0,"size":null,"city":null,"state":"0","weapons":["1","2"],"activities":[],"species":[],"properties":[],"search_text":"lastname"}

更新#2: json 格式的查询正文:

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

【问题讨论】:

  • 构造第一个 match 查询的方式与第二个和第三个查询相同。你的数组太多了。
  • @Val 已更新。现在我收到异常:非法状态异常:在 1:36 时无法在 START_ARRAY 上获取文本
  • 现在您缺少一个 ] 来结束您的阵列。确保方括号是平衡的。
  • @Val 现在平衡了。我恢复了我的更改。
  • 请在您的代码末尾添加 print_r(json_encode($params)) 并向我们展示您的完整 JSON。

标签: elasticsearch elasticsearch-nested


【解决方案1】:

您可以简单地用terms 替换第一个match 查询,因为match 不适用于值数组。

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

            ];

【讨论】:

  • 太棒了,很高兴我们弄明白了。
【解决方案2】:

如果您想检查数组中的任何值是否与索引中的字段匹配,那么您必须使用“术语”而不是匹配。

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

请参阅 ElasticSearch 文档中的“术语级别查询”。

【讨论】:

    猜你喜欢
    • 2017-03-17
    • 2015-08-02
    • 2015-03-12
    • 2017-01-09
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多