我有这个映射:
"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" ] } }
我在这里缺少什么。
谢谢
简短版本: 尝试此操作(更新端点和索引名称后):
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" } } ] } } } } ] } } } } }'
它对我有用,并且简化了您的设置。稍后,我将发布带有较长解释的编辑。
编辑:长版:
查询的问题是分析器与term查询中的过滤器结合在一起。您的分析器将firstName字段文本分解为标记;因此"Test 3"成为令牌"test"和"3"。使用{ "term": { "seller.firstName": "Test 3" } }您要说的是时,找到一个文档,其中的标记之一"seller.firstName"是"Test 3",并且没有任何文档是正确的(实际上,无法给出分析仪的设置方式)。您可以"index": "not_analyzed"在该字段上使用,然后查询就可以使用,也可以使用terms上面显示的过滤器。这是我到达那里的方式:
term
firstName
"Test 3"
"test"
"3"
{ "term": { "seller.firstName": "Test 3" } }
"seller.firstName"
"index": "not_analyzed"
terms
我从您在注释中链接到的索引定义开始,并对其进行了一些简化以使其更具可读性,并且仍然保留以下基本问题:
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"}}'
然后运行查询的简化版本,其基本结构仍然完整,但是使用terms过滤器而不是term过滤器:
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" } } } ] } }
这似乎可以返回您想要的东西。
这是我使用的代码:
http://sense.qbox.io/gist/041dd929106d27ea606f48ce1f86076c52faec91