[英]Elasticsearch multiple filter conditions for nested array
這個問題可能在某個地方回答了,但我找不到。 因此,我需要幫助,但我的產品模型有一個嵌套的屬性列表。 像這樣的東西
[
{
ID: "Product1",
...
Properties: [
{ "Source": "Color", Value: "green"},
{ "Source": "Size", Value: "2"},
]
},
{
ID: "Product2",
...
Properties: [
{ "Source": "Color", Value: "blue"},
{ "Source": "Size", Value: "2"},
]
},
{
ID: "Product3",
....
Properties: [
{ "Source": "Color", Value: "red"},
{ "Source": "Size", Value: "1"},
]
},
]
索引映射:
"properties" : {
"type" : "nested",
"properties" : {
"source" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"value" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
而且我需要搜索查詢才能找到顏色為綠色或藍色且尺寸為2的產品。
我為我的搜索請求創建了此查詢,但它將返回空結果。
new Nest.NestedQuery
{
Path = new Nest.Field("properties"),
Query = new Nest.BoolQuery() {
Must = new Nest.QueryContainer[] {
new Nest.BoolQuery()
{
Must = new Nest.QueryContainer[] {
new Nest.TermQuery()
{
Field = new Nest.Field("properties.source.keyword"),
Value = "Color"
},
new Nest.TermsQuery()
{
Field = new Nest.Field("properties.value.keyword"),
Terms = new[] { "green", "blue"}
}
}
}
},
new Nest.BoolQuery()
{
Must = new Nest.QueryContainer[] {
new Nest.TermQuery()
{
Field = new Nest.Field("properties.source.keyword"),
Value = "Size"
},
new Nest.TermsQuery()
{
Field = new Nest.Field("properties.value.keyword"),
Terms = new[] { "2"}
}
}
}
}
}
}
您能否通過構建這種查詢來幫助我弄錯了什么? 謝謝
嘗試用嵌套查詢包裝每個must子句:
var query = new BoolQuery
{
Must = new QueryContainer[]
{
new NestedQuery
{
Path = "properties",
Query = new BoolQuery()
{
Must = new QueryContainer[]
{
new TermQuery()
{
Field = new Nest.Field("properties.source.keyword"),
Value = "Color"
},
new TermsQuery()
{
Field = new Nest.Field("properties.value.keyword"),
Terms = new[] { "green", "blue"}
}
}
}
},
new NestedQuery
{
Path = "properties",
Query = new BoolQuery()
{
Must = new QueryContainer[]
{
new TermQuery()
{
Field = new Nest.Field("properties.source.keyword"),
Value = "Size"
},
new TermsQuery()
{
Field = new Nest.Field("properties.value.keyword"),
Terms = new[] {"2"}
}
}
}
}
}
};
完整的工作示例
class Program
{
public class Document
{
public int Id { get; set; }
[Nested]
public List<Property> Properties { get; set; }
}
public class Property
{
public string Source { get; set; }
public string Value { get; set; }
public override string ToString() => $"Source: {Source} Value: {Value}";
}
static async Task Main(string[] args)
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings = new ConnectionSettings(pool);
connectionSettings.DefaultIndex("documents");
connectionSettings.DisableDirectStreaming();
connectionSettings.PrettyJson();
var client = new ElasticClient(connectionSettings);
var deleteIndexResponse = await client.Indices.DeleteAsync("documents");
var createIndexResponse = await client.Indices.CreateAsync("documents", d => d
.Map(m => m.AutoMap<Document>()));
var indexDocument = await client
.IndexDocumentAsync(new Document
{
Id = 1,
Properties = new List<Property>
{
new Property {Source = "Color", Value = "green"},
new Property {Source = "Size", Value = "2"},
}
});
indexDocument = await client
.IndexDocumentAsync(new Document
{
Id = 2,
Properties = new List<Property>
{
new Property {Source = "Color", Value = "blue"},
new Property {Source = "Size", Value = "2"},
}
});
indexDocument = await client
.IndexDocumentAsync(new Document
{
Id = 3,
Properties = new List<Property>
{
new Property {Source = "Color", Value = "red"},
new Property {Source = "Size", Value = "1"},
}
});
var refreshAsync = client.Indices.RefreshAsync();
var query = new BoolQuery
{
Must = new QueryContainer[]
{
new NestedQuery
{
Path = "properties",
Query = new BoolQuery()
{
Must = new QueryContainer[]
{
new TermQuery()
{
Field = new Nest.Field("properties.source.keyword"),
Value = "Color"
},
new TermsQuery()
{
Field = new Nest.Field("properties.value.keyword"),
Terms = new[] {"green", "blue"}
}
}
}
},
new NestedQuery
{
Path = "properties",
Query = new BoolQuery()
{
Must = new QueryContainer[]
{
new TermQuery()
{
Field = new Nest.Field("properties.source.keyword"),
Value = "Size"
},
new TermsQuery()
{
Field = new Nest.Field("properties.value.keyword"),
Terms = new[] {"2"}
}
}
}
}
}
};
var response = client.Search<Document>(s => s.Query(q => query));
foreach (var document in response.Documents)
{
Console.WriteLine($"Id: {document.Id}");
document.Properties.ForEach(Console.WriteLine);
Console.WriteLine();
}
}
}
打印:
Id: 1
Source: Color Value: green
Source: Size Value: 2
Id: 2
Source: Color Value: blue
Source: Size Value: 2
希望能有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.