这个问题可能在某个地方回答了,但我找不到。所以我寻求帮助 我的产品模型具有嵌套的属性列表。像这样
[
{
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"}
}
}
}
}
}
}
您能否通过构建这种查询来帮助我弄错了什么? 谢谢
答案 0 :(得分: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
希望有帮助。