【问题标题】:ElasticSearch not returning results for terms query against string propertyElasticSearch 不返回针对字符串属性的术语查询的结果
【发布时间】:2015-09-18 06:28:44
【问题描述】:

我有以下索引文档:

{
    "visitor": {
        "id": <SOME STRING VALUE>
    }
}

文档的映射是:

"visitor": {
    "properties": {
        "id": {
            "type": "string"
         }
     }
 }

当我运行以下查询时,我会得到结果:

{
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
             }
        },
        "filter": {
            "term": { "visitor.id": "123" }
        }
    }
}

但事实并非如此:

{
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
             }
        },
        "filter": {
            "term": { "visitor.id": "ABC" }
        }
    }
}

我一直认为这与分析器有关,并一直在追查。我也一直想知道使用点表示法来访问嵌套的访问者属性是否是错误的。

谁能告诉我为什么我不能过滤 ID 为“ABC”的访问者,但可以过滤访问者 123 的访问者

【问题讨论】:

  • 我对分析仪的预感得到了回报。我发现当将 visitor.id 设置为“abc”而不是“ABC”时,我能够得到预期的结果。我正在研究默认字符串分析器在遇到所有大写字母时会做什么。但是,在我的映射中将字段设置为 "index": "not_analyzed" 解决了这个问题。 “访问者”:{“属性”:{“id”:{“类型”:“字符串”“索引”:“not_analyzed”} } }
  • 正是如此。这个问题的变体每周出现数十次。您可能会发现这篇文章感兴趣:found.no/foundation/beginner-troubleshooting :)
  • 感谢您的帖子,亚历克斯。这很有帮助。它链接到的帖子:found.no/foundation/text-analysis-part-1 更有帮助。
  • 初学者帖子旨在阐明一些未知数,将它们的深度留给其他文章。很高兴你喜欢他们! :)

标签: elasticsearch


【解决方案1】:

您需要了解 elasticsearch 的分析器是如何工作的。分析器执行标记化(将输入拆分为一堆标记,例如空格)和一组标记过滤器(过滤掉您不想要的标记,例如stop words,或修改标记,例如lowercase token filter它将所有内容都转换为小写)。

分析在两个非常具体的时间执行 - 在索引期间(当您将内容放入弹性搜索时),以及根据您的查询,在搜索期间(在您正在搜索的字符串上)。

也就是说,默认分析器是 standard analyzer,它由 standard tokenizerstandard token filter(用于从标准标记器中清除标记)、lowercase token filterstop words token filter 组成。

举个例子,当你保存字符串“I love Vincent's pie!”时进入elasticsearch,你使用的是默认的标准分析器,你实际上存储了“i”、“love”、“vincent”、“s”、“pie”。然后,当您尝试使用 term 查询(未分析)搜索“Vincent's”时,您将找不到任何内容,因为“Vincent's”不是这些标记之一!但是,如果您使用 match 查询(经过分析)搜索“Vincent's”,您会发现“I love Vincent's pie!”因为 "vincent" 和 "s" 都找到了匹配项。

底线,要么:

  1. 在搜索自然语言字符串时,使用经过分析的查询,例如 match
  2. 设置分析仪以满足您的需求。如果你想变得复杂,你可以设置一个自定义分析器来执行空格标记器或字母标记器或模式标记器,以及任何你想要的过滤器。这取决于您的用例,但如果您正在处理自然语言句子,我不建议您这样做,因为标准标记器是为自然语言搜索而构建的。
  3. 您可以将该字段设置为不使用具有以下映射的分析器,这应该适合您的需求:

    "visitor": {
        "properties": {
            "id": {
                "type": "string"
                "index": "not_analyzed"
            }
        }
    }
    

请参阅http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/analysis.html 了解更多信息。

【讨论】:

  • 我在 spring 中使用弹性搜索。我需要在 spring 服务器而不是 json 上设置 "index": "not_analyzed"。
  • 链接失效了。
【解决方案2】:

除非您指定不分析的 visitor.id 字段,否则默认情况下会分析每个字段。

这意味着 "ABC" 将被索引为 "abc"小写)。

您必须在LOWER CASE中使用带有字符串的术语查询或术语过滤器。

我希望下面的查询能正常工作。 ^^

{
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
             }
        },
        "filter": {
            "term": { "visitor.id": "abc" }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-14
    相关资源
    最近更新 更多