【问题标题】:Matching with missing spaces in ElasticSearch匹配 ElasticSearch 中缺失的空格
【发布时间】:2013-11-18 16:02:56
【问题描述】:

我有想要在 ElasticSearch 中索引的文档,其中包含一个名为 name 的文本字段。我目前使用snowball 分析器索引名称。但是,我想匹配包含空格和不包含空格的名称。例如,名称为“The Home Depot”的文档应匹配“homedepot”、“home”和“home depot”。此外,具有单个单词名称(如“ExxonMobil”)的文档应匹配“exxon mobil”和“exxonmobil”。

我似乎找不到合适的分析器/过滤器组合来完成此操作。

【问题讨论】:

    标签: lucene elasticsearch


    【解决方案1】:

    我认为解决这个问题最直接的方法是应用Shingle token filter,它不是创建 ngrams 字符,而是创建传入标记的组合。您可以将其添加到您的分析器中,例如:

    filter:
        ........
        my_shingle_filter:
            type: shingle
            min_shingle_size: 2
            max_shingle_size: 3
            output_unigrams: true
            token_separator: ""
    

    您应该注意此过滤器在过滤器链中的位置。在所有令牌分离/删除/替换已经发生之后(即在任何 StopFilters、SynonymFilters、词干分析器等之后),它可能应该在链的后期出现。

    【讨论】:

    • 这听起来很有希望。让我检查一下,我会回复你的。
    【解决方案2】:

    在这种情况下,您可能需要查看 ngram 类型的解决方案。

    Ngram 做了这样的事情:

    鉴于文本 abcd 并使用 ngram 进行分析,您可能会得到标记:

    a
    ab
    abc
    abcd
    b
    bc
    bcd
    c
    cd
    d
    

    以下是可能适合您的设置。

    您可能需要修改过滤器部分。这个特殊的过滤器创建最多 12 个单位长的克和至少两个标记。

    现在,如果您需要它对雪球给您的进一步分析(如水、水、浇水都与令牌水相匹配),您将需要进一步修改。

            "filter": {
                "ngram_filter": {
                    "type": "nGram",
                    "min_gram": 2,
                    "max_gram": 12
                }
            },
            "analyzer": {
                "ngram_index": {
                    "filter": [
                        "lowercase",
                        "ngram_filter"
                    ],
                    "tokenizer": "keyword"
                },
                "ngram_search": {
                    "filter": [
                        "lowercase"
                    ],
                    "tokenizer": "keyword"
                }
            }
        },
    

    这里的想法是在索引时间创建正确的令牌以在搜索时间可用。但是,您在搜索时需要做的就是使这些令牌可用。您无需再次重新应用 ngram 分析器。

    编辑:

    我刚刚注意到的最后一件事,这个要求:“ExxonMobil”应该匹配“exxon mobil”

    可能意味着您需要执行以下操作:

                "ngram_search": {
                    "filter": [
                        "lowercase"
                    ],
                    "tokenizer": "whitespace"
    
                }
    

    注意添加了“空白”标记器而不是关键字。这允许搜索在空白处拆分。

    【讨论】:

    • @DavidPfeffer min_gram 和 max_gram 设置最小和最大 gram 大小。您将需要修改大小以找到适合您的用例的组合。 2/12 应该是一个合理的开始
    • 对,但这些是最小和最大字符数,对吗?这对我没有帮助,因为我需要组合单词,而不是这些单词中的任意字符。
    • 这些计数是克的大小。正如我所说,您可能需要调整最小最大值。您的要求似乎 exonmobile、exon、mobile 和 exon mobile 都应该匹配同一个文档,对吧?如果是这样,我上面的例子应该可以工作。
    • 我了解到您说必须调整克大小。但是,gram 是由单词中的任意文本片段构成的,而不是单词,而只是单词。我不希望“onmobi”匹配。
    • @DavidPfeffer 我明白了,这要求 elasticsearch 了解一些字符串列表以及什么是“有效”字,什么不是,需要在您的最后定义。例如,The Home Depot 包含:The、Home、Depot、Pot、Me、He 和 ExonMobil 包含 Mob、Exo、On,可能还有 Bil。请记住,雪球通过使用常见的语法结构来工作(这就是 waterly 匹配包含水的文档的原因)。也许单词分隔符可以让您朝着正确的方向前进:elasticsearch.org/guide/en/elasticsearch/reference/current/….
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多