2014-02-21 121 views
21

我有以下的索引文件:ElasticSearch不返回结果对字符串属性方面查询

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

我一直在想这与分析仪有关,并一直在追逐下来。我也一直在想,如果我错误地使用点符号来访问嵌套的访客属性。

谁能告诉我为什么我不能用“ABC”的ID,但可以在访客筛选游客123

+2

我对分析仪的预感得到了回报。我发现将visitor.id设置为“abc”而不是“ABC”时,我能够获得预期的结果。我正在研究默认字符串分析器在遇到所有大写字母时会做什么。但是,在我的映射中将字段设置为“索引”:“not_analyzed”解决了问题。 “访客”:{ “属性”:{ “ID”:{ “类型”: “串” “索引”: “not_analyzed” } } } – goatshepard

+4

正是这样。这个问题的变种每周出现几十次。你可能会发现这篇感兴趣的文章:https://www.found.no/foundation/beginner-troubleshooting/ :) –

+0

感谢这篇文章,亚历克斯。这非常有帮助。它链接到的帖子:https://www.found.no/foundation/text-analysis-part-1/更有帮助。 – goatshepard

回答

42

您需要了解elasticsearch的分析器是如何工作的。分析器执行标记(将输入分成许多标记,例如空格)和一组标记过滤器(过滤掉不需要的标记,如stop words或修改标记,如将lowercase token filter转换为一切小写)。

分析是在两个非常特定的时间进行的 - 在索引过程中(当您将东西放入elasticsearch时)以及在搜索过程中(取决于您的查询),您正在搜索的字符串中。

这就是说,默认分析器是它由一个standard tokenizerstandard token filter(清理从标准标记生成器的令牌)的standard analyzerlowercase token filter,和stop words token filter

举个例子,当你保存字符串“我爱文森特的馅饼!”进入elasticsearch,你使用的是默认的标准分析器,你实际上存储着“我”,“爱”,“文森”,“s”,“派”。然后,当您尝试使用term查询(这是未分析)搜索“Vincent's”时,您将找不到任何内容,因为“Vincent's”不是这些令牌之一!但是,如果您使用match查询(它是分析)搜索“Vincent's”,您会发现“我爱文森特的馅饼!”因为“文森特”和“S”都找到匹配。

底线,或者:

  1. 搜索自然语言字符串时使用的分析后的查询,如match
  2. 设置分析仪以满足您的需求。你可以建立一个自定义的分析器,如果你想变得复杂,你可以设置一个自定义分析器来执行一个空白分词器或一个字母分词器或一个模式分词器,以及任何你想要的滤波器。这取决于你的用例,但如果你在处理自然语言句子,我不建议这样做,因为标准词源化程序是为自然语言搜索而构建的。
  3. 您可以设置字段,可达到不使用分析仪下面的映射,它应该满足您的需求:

    ​​

进一步的阅读可见http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/analysis.html

16

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

这意味着“ABC”将被索引为“ABC”小写)。

您必须使用带字符串的字词查询或字词过滤器小写字母

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

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

你节省了我的一天,非常感谢! –

相关问题