elasticsearch.net(NEST) 中的等效 linq 查询
Equivalent linq query in elasticsearch.net(NEST)
我在 elastic 中有以下文件类型:
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 库编写以下 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
};
}
是这样的吗?
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));
ProductSuppliers
中的 ProductSupplierDto
将被映射为具有自动映射的 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
}
}
}
]
}
}
}
几点
- 查询使用 operator overloading on queries 将它们组合在一起并生成在筛选器上下文中执行的查询(在本例中为
bool
查询 filter
子句)。由于文档匹配或不匹配,因此不需要计算匹配的相关性分数。
f => f.ProductSuppliers[0].Enabled
是获取字段路径的表达式。不是"get the value of Enabled
from the first item in ProductSuppliers
",而是"get the path to the Enabled
field of all items in the ProductSuppliers
property"。此处集合中的索引器 仅 能够访问 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)
)
)
)
);
我在 elastic 中有以下文件类型:
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 库编写以下 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
};
}
是这样的吗?
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));
ProductSuppliers
中的 ProductSupplierDto
将被映射为具有自动映射的 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
}
}
}
]
}
}
}
几点
- 查询使用 operator overloading on queries 将它们组合在一起并生成在筛选器上下文中执行的查询(在本例中为
bool
查询filter
子句)。由于文档匹配或不匹配,因此不需要计算匹配的相关性分数。 f => f.ProductSuppliers[0].Enabled
是获取字段路径的表达式。不是"get the value ofEnabled
from the first item inProductSuppliers
",而是"get the path to theEnabled
field of all items in theProductSuppliers
property"。此处集合中的索引器 仅 能够访问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)
)
)
)
);