我的弹性文档类型如下:
public class ProductDto
{
public Int64 Id { get; set; }
public String Title{ get; set; }
public bool Visible { get; set; }
public IList<ProductSupplierDto> ProductSuppliers { get; set; }
}
public class ProductSupplierDto
{
public Int64 Id { get; set; }
public String Title{ get; set; }
public bool Enabled { get; set; }
}
如何使用Nest libray在linq查询下编写内容:
var products = db.products.where(p=> p.Visible
&& p.ProductSuppliers.Any(ps=>ps.Enabled)
).ToList();
在嵌套库中,我有以下查询:
var baseQuery = Query<ProductDto>.Term(qt => qt.Field(f =>
f.Visible).Value(true));
如何在baseQuery中添加产品供应商过滤器?
我使用此方法创建索引:
private async Task CreateIndexIfItDoesntExist<T>(string index) where T: class
{
if (!this.client.IndexExists(index).Exists)
{
var indexDescriptor = new CreateIndexDescriptor(index)
.Settings(x => x.NumberOfReplicas(0))
.Mappings(mappings => mappings
.Map<T>(m => m.AutoMap()));
await this.client.CreateIndexAsync(index, i => indexDescriptor);
// Max out the result window so you can have pagination for >100 pages
await this.client.UpdateIndexSettingsAsync(index, ixs => ixs
.IndexSettings(s => s
.Setting("max_result_window", int.MaxValue)));
}
}
并像这样调用:
await CreateIndexIfItDoesntExist<ProductDto>("products");
索引数据方法:
private async Task<IndexResult> IndexDocuments<T>(T[] datas, string index) where T:class
{
int batchSize = 1000; // magic
int totalBatches = (int)Math.Ceiling((double)datas.Length / batchSize);
for (int i = 0; i < totalBatches; i++)
{
var response = await this.client.IndexManyAsync(datas.Skip(i * batchSize).Take(batchSize), index);
if (!response.IsValid)
{
return new IndexResult
{
IsValid = false,
ErrorReason = response.ServerError?.Error?.Reason,
Exception = response.OriginalException
};
}
else
{
Debug.WriteLine($"Successfully indexed batch {i + 1}");
}
}
return new IndexResult
{
IsValid = true
};
}
答案 0 :(得分:1)
ProductSupplierDto
中的 ProductSuppliers
将被映射为具有自动映射的object
类型,因此以下查询将实现您想要的
var client = new ElasticClient();
var searchResponse = client.Search<ProductDto>(s => s
.Query(q => +q
.Term(f => f.Visible, true) && +q
.Term(f => f.ProductSuppliers[0].Enabled, true)
)
);
这会生成以下查询
{
"query": {
"bool": {
"filter": [
{
"term": {
"visible": {
"value": true
}
}
},
{
"term": {
"productSuppliers.enabled": {
"value": true
}
}
}
]
}
}
}
几点
bool
查询filter
子句)。由于文档匹配或不匹配,因此无需计算匹配的相关性得分。f => f.ProductSuppliers[0].Enabled
是用于获取字段路径的表达式。这并不意味着”从Enabled
的第一项中获取ProductSuppliers
的值” ,而是”获取到Enabled
字段的路径ProductSuppliers
属性中的所有项目” 。只能使用 进入集合中的索引器,以便能够访问ProductSupplierDto
类型的属性。您可能想要consider mapping ProductSuppliers
as a nested
type,以便能够在ProductSuppliers
集合中的各个项目的属性之间进行查询。将ProductSuppliers
映射为nested
类型后,查询将为
var searchResponse = client.Search<ProductDto>(s => s
.Query(q => +q
.Term(f => f.Visible, true) && +q
.Nested(n => n
.Path(p => p.ProductSuppliers)
.Query(nq => nq
.Term(f => f.ProductSuppliers[0].Enabled, true)
)
)
)
);
答案 1 :(得分:-1)
像这样吗?
QueryContainer baseQuery = Query<ProductDto>.Term(qt => qt.Field(f =>
f.Visible).Value(true));
baseQuery &= Query<ProductDto>.Term(qt => qt.Field(o => o.ProductSuppliers.Select(a => a.Enabled)).Value(true));
client.Search<ProductDto>(o => o
.From(0)
.Size(10)
.Query(a => baseQuery));