我正在玩弄 Elasticsearch 和 NEST。
我确实很难理解可用于创建和构建静态查询的各种类和接口(interface)。
这是我想要实现的目标的简化示例:
using Nest;
using System;
using System.Text;
namespace NestTest
{
public class Product
{
public string Name { get; set; }
public int Price { get; set; }
}
public class ProductFilter
{
public string[] IncludeNames { get; set; }
public string[] ExcludeNames { get; set; }
public int MaxPrice { get; set; }
}
class Program
{
static void Main(string[] args)
{
var filter = new ProductFilter();
filter.MaxPrice = 100;
filter.IncludeNames = new[] { "Notebook", "Workstation" };
filter.ExcludeNames = new[] { "Router", "Modem" };
var query = CreateQueryFromFilter(filter);
var client = new ElasticClient();
// Test Serialization
var serialized = Encoding.UTF8.GetString(client.Serializer.Serialize(query));
Console.WriteLine(serialized);
// TODO: How to convert the IQuery to QueryContainer?
//client.Search<Product>(s => s.Query(q => query));
}
private static IQuery CreateQueryFromFilter(ProductFilter filter)
{
var baseBoolean = new BoolQueryDescriptor<Product>();
if (filter.IncludeNames != null && filter.IncludeNames.Length > 0)
{
foreach (var include in filter.IncludeNames)
{
// TODO: This overwrites the previous must
baseBoolean.Must(q => q.Term(t => t.Name, include));
}
}
if (filter.ExcludeNames != null && filter.ExcludeNames.Length > 0)
{
foreach (var exclude in filter.ExcludeNames)
{
// TODO: This overwrites the previous must
baseBoolean.MustNot(q => q.Term(t => t.Name, exclude));
}
}
if (filter.MaxPrice > 0)
{
// TODO: This overwrites the previous must
baseBoolean.Must(q => q.Range(r => r.LowerOrEquals(filter.MaxPrice).OnField(f => f.Price)));
}
return baseBoolean;
}
}
}
如您所见,我想创建某种查询对象(很可能是 BoolQuery),然后稍后填充该对象。我在遇到实际问题的代码中添加了一些 TODOS。但总的来说,可能性太多(IQuery、QueryContainer、XXXQueryDescriptor、SearchDescriptor、SearchRequest),我不知道如何成功地逐部分“构建”查询。
谁能教教我?
最佳答案
组合 bool 查询在此处的文档中进行了描述:
http://nest.azurewebsites.net/nest/writing-queries.html
该页面有点过时,很快就会更新,尽管其中大部分内容仍然适用我更新了您的 CreateQueryFromFilter
方法以展示您可以制定查询的几种方式:
private static IQueryContainer CreateQueryFromFilter(ProductFilter filter)
{
QueryContainer queryContainer = null;
if (filter.IncludeNames != null && filter.IncludeNames.Length > 0)
{
foreach (var include in filter.IncludeNames)
{
//using object initializer syntax
queryContainer &= new TermQuery()
{
Field = Property.Path<Product>(p => p.Name),
Value = include
};
}
}
if (filter.ExcludeNames != null && filter.ExcludeNames.Length > 0)
{
foreach (var exclude in filter.ExcludeNames)
{
//using static Query<T> to dispatch fluent syntax
//note the ! support here to introduce a must_not clause
queryContainer &= !Query<Product>.Term(p => p.Name, exclude);
}
}
if (filter.MaxPrice > 0)
{
//fluent syntax through manually newing a descriptor
queryContainer &= new QueryDescriptor<Product>()
.Range(r => r.LowerOrEquals(filter.MaxPrice).OnField(f => f.Price)
);
}
return queryContainer;
}
以下是将其传递给搜索操作的方法:
static void Main(string[] args)
{
//using the object initializer syntax
client.Search<Product>(new SearchRequest()
{
Query = query
});
//using fluent syntax
client.Search<Product>(s => s.Query(query));
}
关于c# - 使用 NEST 构建静态查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25212178/