我有一个索引,其中包含我要命中的项目的嵌套集合。集合项包含多个必须全部与某个查询匹配的属性,而不仅仅是其中的任何一个。这是模型:
public class IndexEntry1 { public IEnumerable<NestedType1> NestedProperty1 { get; set; } } public class NestedType1 { public string Member1 { get; set; } public string Member2 { get; set; } }
因此,我只想点击集合中具有Member1和Member2值特定组合的文档IndexEntry1.NestedProperty1。
Member1
Member2
IndexEntry1.NestedProperty1
我认为必须将集合映射为嵌套。
这是映射:
index: { properties: { nestedProperty1: { type: "nested", properties: { member1: { type: "string", index_analyzer: "my_index_analyzer_1", search_analyzer: "my_search_analyzer_1" }, member2: { type: "string", analyzer: "keyword" } } } }, analysis: { tokenizer: { my_ngram: { type: "nGram", min_gram: "1", max_gram: "15" } }, analyzer: { my_index_analyzer_1: { type: "custom", tokenizer: "my_ngram", filters: ["lowercase"] }, my_search_analyzer_1: { type: "custom", tokenizer: "whitespace", filters: ["lowercase"] } } } }
并使用如下查询:
client.Search<IndexEntry1>(d => d .Query(query => query .Nested(n => n .Path(p => p.NestedProperty1) .Query(q => q .Bool(b => b .Must( m => m.Term("member1", "value1"), m => m.QueryString(s => s.OnField("member2") .Query("value2"))))))));
但是,我仍然会遇到具有该value1值或该value2值的任何文档的命中,而我希望仅对具有相同值的两个值在同一NestedProperty1收集项目上的文档进行命中。
value1
value2
NestedProperty1
您是正确的,它只应查找嵌套文档具有value1和value2的文档。
您可以通过合理运行以下命令(chrome插件)来观察这是Elasticsearch的行为:
PUT http://localhost:9200/nested_example { "mappings": { "indexentry" : { "properties": { "nestedCollection": { "type": "nested", "properties": { "prop1" : { "type": "string", "index": "not_analyzed" }, "prop2" : { "type": "string", "index": "not_analyzed" } } } } } } } POST http://localhost:9200/nested_example/indexentry/1 { "nestedCollection": [ { "prop1" : "A", "prop2" : "A" }, { "prop1" : "B", "prop2" : "B" } ] } POST http://localhost:9200/nested_example/indexentry/2 { "nestedCollection": [ { "prop1" : "C", "prop2" : "C" }, { "prop1" : "D", "prop2" : "D" } ] } POST http://localhost:9200/nested_example/indexentry/_search { "query": { "nested": { "path": "nestedCollection", "query": { "bool": { "must": [ { "term": { "nestedCollection.prop1": { "value": "A" } } }, { "term": { "nestedCollection.prop2": { "value": "A" } } } ] } } } } }
先前的查询将仅找到文档,1但是一旦您更改术语查询nestedColleciton.prop2以查找B而不是A您,将不再获得预期的任何响应。
1
nestedColleciton.prop2
B
A
如果我更新该示例以使其更符合您的映射和查询,则无法重现您的见证行为:
PUT http://localhost:9200/nested_example { "settings": { "analysis": { "tokenizer": { "my_ngram": { "type": "nGram", "min_gram": "1", "max_gram": "15" } }, "analyzer": { "my_index_analyzer_1": { "type": "custom", "tokenizer": "my_ngram", "filters": [ "lowercase" ] }, "my_search_analyzer_1": { "type": "custom", "tokenizer": "whitespace", "filters": [ "lowercase" ] } } } }, "mappings": { "indexentry": { "properties": { "nestedCollection": { "type": "nested", "properties": { "prop1": { "type": "string", "index_analyzer": "my_index_analyzer_1", "search_analyzer": "my_search_analyzer_1" }, "prop2": { "type": "string", "analyzer": "keyword" } } } } } } } POST http://localhost:9200/nested_example/indexentry/1 { "nestedCollection": [ { "prop1" : "value1", "prop2" : "value1" }, { "prop1" : "value2", "prop2" : "value2" } ] } POST http://localhost:9200/nested_example/indexentry/2 { "nestedCollection": [ { "prop1" : "value3", "prop2" : "value3" }, { "prop1" : "value4", "prop2" : "value4" } ] } POST http://localhost:9200/nested_example/indexentry/_search { "query": { "nested": { "path": "nestedCollection", "query": { "bool": { "must": [ { "term": { "prop1": { "value": "value1" } } }, { "query_string": { "fields": [ "prop2" ], "query": "value1" } } ] } } } } }
您可以更新前面的示例以更好地重现您的情况吗?
在NEST中,您可以将查询重写为:
client.Search<IndexEntry1>(d => d .Query(query => query .Nested(n => n .Path(p => p.NestedProperty1) .Query(q => q.Term(p => p.NestedProperty1.First().Member1, "value1") && q.QueryString(s => s .OnField(p => p.NestedPropery1.First().Member2) .Query("value2") ) ) ) );
类型强,嵌套少。