我有以下索引文档:
{
"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为&#34; ABC&#34;但可以为访客123
答案 0 :(得分:48)
您需要了解elasticsearch的分析仪的工作原理。分析器执行标记化(将输入拆分为一堆标记,例如在空格上)和一组标记过滤器(过滤掉您不想要的标记,如stop words)或修改标记,如{ {3}}将所有内容转换为小写。)
分析是在两个非常特定的时间执行的 - 在索引期间(当您将内容放入elasticsearch时),并且根据您的查询,在搜索期间(在您正在搜索的字符串上)。
也就是说,默认分析器是lowercase token filter,其中包含standard analyzer,standard tokenizer(用于清除标准标记生成器中的标记),standard token filter和{ {3}}
举一个例子,当你保存字符串“我爱文森特的馅饼!”进入elasticsearch,你正在使用默认的标准分析器,你实际上存储的是“我”,“爱”,“文森特”,“s”,“馅饼”。然后,当您尝试使用term
查询(未分析)搜索“Vincent's”时,您将找不到任何内容,因为“Vincent's”不是其中一个令牌!但是,如果您使用match
查询(已分析)搜索“Vincent's”,您会发现“我爱文森特的馅饼!”因为“vincent”和“s”都找到了匹配。
底线是:
match
。您可以将字段设置为不使用具有以下映射的分析器,该映射应该符合您的需求:
"visitor": {
"properties": {
"id": {
"type": "string"
"index": "not_analyzed"
}
}
}
有关详细信息,请参阅lowercase token filter。
答案 1 :(得分:23)
除非您指定不要分析的visitor.id字段,否则默认情况下会分析每个字段。
这意味着“ABC”将被编入索引为“abc”(小写)。
你必须在 LOWER CASE 中使用术语查询或术语过滤器和字符串。
我希望下面的查询能够正常运行。 ^^
{
"query": {
"filtered": {
"query": {
"match_all": {}
}
},
"filter": {
"term": { "visitor.id": "abc" }
}
}
}