我正在使用ElasticSearch 6.2.3开发自动完成程序。我希望使用以下优先级对我的查询结果(带有名称字段的页面列表)进行排序:
我将使用包含三个查询的Bool / Should查询(对应于上面的三个优先级),使用boost来定义相对重要性。
我遇到的问题是使用前缀查询 - 尽管我的搜索分析器具有小写过滤器,但它似乎并没有降低搜索查询的范围。例如,下面的查询为'harry'返回“Harry Potter”,但为'Harry'返回零结果:
{ "query": { "prefix": { "Name.raw" : "Harry" } } }
我已经使用_analyze
API验证了我的两个分析器确实将“Harry”文本小写为“harry”。我哪里错了?
从ES文档中我了解到,我需要以两种不同的方式分析Name字段,以便能够同时使用Prefix和Term查询:
使用“关键字”标记生成器启用Prefix查询(我已将此应用于.raw
字段)
使用标准分析器启用Term(我已在名称字段中应用此功能)
我检查过this one等重复问题,但答案没有帮助
我的地图和设置位于
之下ES索引映射
{
"myIndex": {
"mappings": {
"pages": {
"properties": {
"Id": {},
"Name": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"analyzer": "keywordAnalyzer",
"search_analyzer": "pageSearchAnalyzer"
}
},
"analyzer": "pageSearchAnalyzer"
},
"Tokens": {}, // Other fields not important for this question
}
}
}
}
}
ES索引设置
{
"myIndex": {
"settings": {
"index": {
"analysis": {
"filter": {
"ngram": {
"type": "edgeNGram",
"min_gram": "2",
"max_gram": "15"
}
},
"analyzer": {
"keywordAnalyzer": {
"filter": [
"trim",
"lowercase",
"asciifolding"
],
"type": "custom",
"tokenizer": "keyword"
},
"pageSearchAnalyzer": {
"filter": [
"trim",
"lowercase",
"asciifolding"
],
"type": "custom",
"tokenizer": "standard"
},
"pageIndexAnalyzer": {
"filter": [
"trim",
"lowercase",
"asciifolding",
"ngram"
],
"type": "custom",
"tokenizer": "standard"
}
}
},
"number_of_replicas": "1",
"uuid": "l2AXoENGRqafm42OSWWTAg",
"version": {}
}
}
}
}
答案 0 :(得分:1)
前缀查询不会分析搜索词,因此传递给它的文本会绕过用作搜索分析器的任何内容(在您的情况下,配置为search_analyzer: pageSearchAnalyzer
)并将Harry
评估为 - 直接针对关键字标记化,自定义过滤的harry potter
,这是在索引时应用keywordAnalyzer
的结果。
在这种情况下,你需要做一些不同的事情:
lowercase
过滤器,因此您可以始终在前缀查询中使用小写字词(如果需要,使用应用程序端小写)match
分析的字段而不是edge_ngram
prefix
查询运行PUT my_index
{
"settings": {
"index": {
"analysis": {
"filter": {
"ngram": {
"type": "edgeNGram",
"min_gram": "2",
"max_gram": "15"
}
},
"analyzer": {
"pageIndexAnalyzer": {
"filter": [
"trim",
"lowercase",
"asciifolding",
"ngram"
],
"type": "custom",
"tokenizer": "keyword"
}
}
}
}
},
"mappings": {
"pages": {
"properties": {
"name": {
"type": "text",
"fields": {
"ngram": {
"type": "text",
"analyzer": "pageIndexAnalyzer",
"search_analyzer": "standard"
}
}
}
}
}
}
}
个查询
醇>
以下是后者的一个例子:
1)创建索引w / ngram分析器和(推荐)标准搜索分析器
POST my_index/pages/_bulk
{"index":{}}
{"name":"Harry Potter"}
{"index":{}}
{"name":"Hermione Granger"}
2)索引一些示例文档
POST my_index/pages/_search
{
"query": {
"match": {
"query": "Har",
"operator": "and"
}
}
}
3)针对ngram字段运行匹配查询
C
答案 1 :(得分:0)
我认为最好使用match_phrase_prefix
查询而不使用后缀.keyword
。在此处https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase-prefix.html