elasticsearch嵌套筛选器返回空结果
我有以下映射:elasticsearch嵌套筛选器返回空结果,search,filter,elasticsearch,nested,Search,Filter,elasticsearch,Nested,我有以下映射: "post": { "model": "Post", "properties": { "id": { "type": "integer" }, "title": { "type": "string", "analyzer": "custom_analyzer", "boost": 5 }, "description": {
"post": {
"model": "Post",
"properties": {
"id": {
"type": "integer"
},
"title": {
"type": "string",
"analyzer": "custom_analyzer",
"boost": 5
},
"description": {
"type": "string",
"analyzer": "custom_analyzer",
"boost": 4
},
"condition": {
"type": "integer",
"index": "not_analyzed"
},
"categories": {
"type": "string",
"index": "not_analyzed"
},
"seller": {
"type": "nested",
"properties": {
"id": {
"type": "integer",
"index": "not_analyzed"
},
"username": {
"type": "string",
"analyzer": "custom_analyzer",
"boost": 1
},
"firstName": {
"type": "string",
"analyzer": "custom_analyzer",
"boost": 3
},
"lastName": {
"type": "string",
"analyzer": "custom_analyzer",
"boost": 2
}
}
},
"marketPrice": {
"type": "float",
"index": "not_analyzed"
},
"currentPrice": {
"type": "float",
"index": "not_analyzed"
},
"discount": {
"type": "float",
"index": "not_analyzed"
},
"commentsCount": {
"type": "integer",
"index": "not_analyzed"
},
"likesCount": {
"type": "integer",
"index": "not_analyzed"
},
"featured": {
"type": "boolean",
"index": "not_analyzed"
},
"bumped": {
"type": "boolean",
"index": "not_analyzed"
},
"created": {
"type": "date",
"index": "not_analyzed"
},
"modified": {
"type": "date",
"index": "not_analyzed"
}
}
}
此查询:
GET /develop/_search?search_type=dfs_query_then_fetch
{
"query": {
"filtered" : {
"query": {
"bool": {
"must": [
{ "match": { "title": "post" }}
]
}
},
"filter": {
"bool": {
"must": [
{"term": {
"featured": 0
}},
{
"nested": {
"path": "seller",
"filter": {
"bool": {
"must": [
{ "term": { "seller.firstName": "Test 3" } }
]
}
},
"_cache" : true
}}
]
}
}
}
},
"sort": [
{
"_score":{
"order": "desc"
}
},{
"created": {
"order": "desc"
}
}
],
"track_scores": true
}
我等待25个结果,因为我有25个后期索引。但我有一套空的。如果我删除嵌套过滤器,所有的工作都很好。我希望能够筛选嵌套对象
编辑:
在我的设置中,我有:
"analyzer": {
"custom_analyzer": {
"type": "custom",
"tokenizer": "nGram",
"filter": [
"stopwords",
"asciifolding",
"lowercase",
"snowball",
"english_stemmer",
"english_possessive_stemmer",
"worddelimiter"
]
},
"custom_search_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"stopwords",
"asciifolding",
"lowercase",
"snowball",
"english_stemmer",
"english_possessive_stemmer",
"worddelimiter"
]
}
}
我错过了什么
谢谢简短版本:请尝试(在更新端点和索引名称后): 它为我工作,与您的设置简化版本。过一会儿我会发布一个带有较长解释的编辑 编辑:长版本: 查询中的问题是分析器与查询中的
术语
过滤器相结合。您的分析器正在将firstName
字段的文本分解为标记;因此“Test 3”
成为标记“Test”
和“3”
。当您使用{“term”:{“seller.firstName”:“Test 3”}
时,您要说的是,找到一个文档,其中“seller.firstName”
的一个标记是“Test 3”
,并且没有任何文档是正确的(事实上,无法给出分析器的设置方式)。您可以在该字段上使用“index”:“not_analysis”
,然后您的查询就可以工作了,或者您也可以像上面所显示的那样使用术语
过滤器。我是这样到达那里的:
我从您在评论中链接的索引定义开始,并对其进行了一些简化,使其更具可读性,同时仍然保留了基本问题:
curl -XDELETE "http://localhost:9200/my_index"
curl -XPUT "http://localhost:9200/my_index" -d'
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"analysis": {
"filter": {
"snowball": { "type": "snowball", "language": "English" },
"english_stemmer": { "type": "stemmer", "language": "english" },
"english_possessive_stemmer": { "type": "stemmer", "language": "possessive_english" },
"stopwords": { "type": "stop", "stopwords": [ "_english_" ] },
"worddelimiter": { "type": "word_delimiter" }
},
"tokenizer": {
"nGram": { "type": "nGram", "min_gram": 3, "max_gram": 20 }
},
"analyzer": {
"custom_analyzer": {
"type": "custom",
"tokenizer": "nGram",
"filter": [
"stopwords",
"asciifolding",
"lowercase",
"snowball",
"english_stemmer",
"english_possessive_stemmer",
"worddelimiter"
]
},
"custom_search_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"stopwords",
"asciifolding",
"lowercase",
"snowball",
"english_stemmer",
"english_possessive_stemmer",
"worddelimiter"
]
}
}
}
},
"mappings": {
"posts": {
"properties": {
"title": {
"type": "string",
"analyzer": "custom_analyzer",
"boost": 5
},
"seller": {
"type": "nested",
"properties": {
"firstName": {
"type": "string",
"analyzer": "custom_analyzer",
"boost": 3
}
}
}
}
}
}
}'
然后我添加了一些测试文档:
curl -XPUT "http://localhost:9200/my_index/posts/1" -d'
{"title": "post", "seller": {"firstName":"Test 1"}}'
curl -XPUT "http://localhost:9200/my_index/posts/2" -d'
{"title": "post", "seller": {"firstName":"Test 2"}}'
curl -XPUT "http://localhost:9200/my_index/posts/3" -d'
{"title": "post", "seller": {"firstName":"Test 3"}}'
然后运行简化版的查询,基本结构保持不变,但使用术语
过滤器而不是术语
过滤器:
curl -XPOST "http://localhost:9200/my_index/_search?search_type=dfs_query_then_fetch" -d'
{
"query": {
"filtered": {
"query": {
"bool": {
"must": [
{
"match": {
"title": "post"
}
}
]
}
},
"filter": {
"bool": {
"must": [
{
"nested": {
"path": "seller",
"filter": {
"bool": {
"must": [
{
"terms": {
"seller.firstName": [
"test",
"3"
],
"execution": "and"
}
}
]
}
}
}
}
]
}
}
}
}
}'
...
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 6.085842,
"hits": [
{
"_index": "my_index",
"_type": "posts",
"_id": "3",
"_score": 6.085842,
"_source": {
"title": "post",
"seller": {
"firstName": "Test 3"
}
}
}
]
}
}
这似乎能回报你想要的
以下是我使用的代码:
您可以发布您对
自定义分析仪的定义吗?它的设置方式可能与你的问题有关。嘿@SloanAhrens我用我的分析更新了问题我仍然无法设置像你这样的索引来测试它。看起来您也定义了一些自定义筛选器?你能把这些也发出去吗?一些示例文档可能也会有所帮助。如果不能够模拟您的系统,很难告诉您问题出在哪里。不过,我怀疑,在您当前的设置中,{“term”:{“seller.firstName”:“Test 3”}
需要是{“term”:{“seller.firstName”:“Test”}
或类似的内容。或者,您需要调整分析仪/映射。但如果不直接测试,就很难确定了。@SloanAhrens在这个问题上,我发布了相同的数据和映射,但出于不同的原因,它的工作原理相同,但ES不应该为我这样做?如何指定要在筛选器中使用的分析器?因为如果我必须对搜索文本进行分析,我自己可以非常认真地阅读我刚才所做的编辑,看看它是否回答了你的问题。如果没有,我会看看是否可以更新。我想你会想修改你的分析器,和/或使用一个multi_字段。谢谢Sloan,在你发布答案后,我知道自定义_分析器正在拆分字段,但是我想让它在查询中使用自定义搜索分析器,所以在使用过滤器的时候,它会自己分割文本,所以我不需要自己分割文本,以这种方式构建查询。我还有另外一个关于“多重匹配”的查询:{“查询”:“帖子”,“字段”:[“标题”,“描述”],“分析器”:“自定义搜索分析器”}其中我想做一些类似的事情。对不起,我不确定我是否理解你的问题。你试过你的建议了吗?也许值得再问一个StackOverflow问题?是的,我试过了,但是我得到了一个错误,因为我没有找到让过滤器使用自定义分析器的方法。我再问一个问题。谢谢
curl -XPOST "http://localhost:9200/my_index/_search?search_type=dfs_query_then_fetch" -d'
{
"query": {
"filtered": {
"query": {
"bool": {
"must": [
{
"match": {
"title": "post"
}
}
]
}
},
"filter": {
"bool": {
"must": [
{
"nested": {
"path": "seller",
"filter": {
"bool": {
"must": [
{
"terms": {
"seller.firstName": [
"test",
"3"
],
"execution": "and"
}
}
]
}
}
}
}
]
}
}
}
}
}'
...
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 6.085842,
"hits": [
{
"_index": "my_index",
"_type": "posts",
"_id": "3",
"_score": 6.085842,
"_source": {
"title": "post",
"seller": {
"firstName": "Test 3"
}
}
}
]
}
}