首页 > 解决方案 > 如何在弹性嵌套查询中查询 * 值?

问题描述

我有这样的嵌套条目的文档:

"listOfElements": {
    "entries": [{
            "key1": "value1",
            "key2": "value2"
        }, {
            "key1": "value3",
            "key2": "*"
        }
    ]
}

因此,第二个条目中的 * 是一个实际的字符串值,而不是通配符。

现在我正在尝试使用以下正文查询所有带有 key1:value3 和 key2:* 的文档:

{
    "query": {
        "nested" : {
            "path" : "listOfElements.entries",
            "score_mode" : "avg",
            "query" : {
                "bool" : {
                    "must" : [
                    { "match" : {"listOfElements.entries.key1" : "value3"} },
                    { "match" : {"listOfElements.entries.key2" : "*" } }
                    ]
                }
            }
        }
    }
}

但是,这根本不会返回任何文档。

此外,使用 "\\*" 作为 key2 的查询参数也无济于事。

是否甚至可以将 * 作为实际的字符串值而不是通配符进行查询?

在第一个答案后编辑并提示分析器设置:尝试将我的索引配置为使用 Elastic 文档中描述的映射 char_filter:

"settings": {
    "analysis": {
        "analyzer": {
            "rebuilt_standard": {
                "tokenizer": "standard",
                "char_filter": [
                    "replace_star_filter"
                ]
            }
        },
        "char_filter": {
            "replace_star_filter": {
                "type": "mapping",
                "mappings": [
                    "* => _star_"
                ]
            }
        }
    }
}

如果我手动调用分析 URL,例如使用此正文,则此方法有效

{
  "analyzer": "rebuilt_standard",
  "text": "I'm delighted about it *"
}

我得到以下回复:

{
    "tokens": [
        {
            "token": "I'm",
            "start_offset": 0,
            "end_offset": 3,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "delighted",
            "start_offset": 4,
            "end_offset": 13,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "about",
            "start_offset": 14,
            "end_offset": 19,
            "type": "<ALPHANUM>",
            "position": 2
        },
        {
            "token": "it",
            "start_offset": 20,
            "end_offset": 22,
            "type": "<ALPHANUM>",
            "position": 3
        },
        {
            "token": "_star_",
            "start_offset": 23,
            "end_offset": 24,
            "type": "<ALPHANUM>",
            "position": 4
        }
    ]
}

编辑2:我终于设法让它工作了。我必须事先配置映射,以便特定字段使用我的自定义分析器。对我来说,棘手且出乎意料的是,当我运行搜索查询时,它会向我显示带有 * 的原始文档,但如果我使用 JSON 正文从 API 运行查询,那么我可以使用星号并获得匹配.

标签: elasticsearch

解决方案


您的搜索语法是正确的,我认为问题在于您正在搜索的值以及您的索引使用的更准确的分析器。

我假设您使用的是标准分析器(除非指定不同,否则您的索引也是默认的),基本上这意味着并非所有数据都被索引只是其中的一部分,您应该进一步阅读哪些分析器做但是,如果您想保存特定的非 ALPHANUMERIC 字符,例如 *,您将必须创建一个自定义分析器。

TLDR:

好消息是的,可以创建一个自定义分析器来索引特殊字符 *。坏消息这意味着从头开始创建一个新索引并将所有数据重新索引到其中。

您可以在此处阅读有关如何更轻松地进行操作的信息


推荐阅读