elasticsearch,builder,nest,C#,Static,elasticsearch,Builder,Nest" /> elasticsearch,builder,nest,C#,Static,elasticsearch,Builder,Nest" />

C# 带嵌套的静态查询构建

C# 带嵌套的静态查询构建,c#,static,elasticsearch,builder,nest,C#,Static,elasticsearch,Builder,Nest,我在玩Elasticsearch和NEST 我在理解可用于创建和构建静态查询的各种类和接口时遇到了一些困难 下面是我想要实现的一个简化示例: 使用Nest; 使用制度; 使用系统文本; 名称空间嵌套测试 { 公共类产品 { 公共字符串名称{get;set;} 公共整数价格{get;set;} } 公共类产品过滤器 { 公共字符串[]IncludeNames{get;set;} 公共字符串[]ExcludeNames{get;set;} public int MaxPrice{get;set;}

我在玩Elasticsearch和NEST

我在理解可用于创建和构建静态查询的各种类和接口时遇到了一些困难

下面是我想要实现的一个简化示例:

使用Nest;
使用制度;
使用系统文本;
名称空间嵌套测试
{
公共类产品
{
公共字符串名称{get;set;}
公共整数价格{get;set;}
}
公共类产品过滤器
{
公共字符串[]IncludeNames{get;set;}
公共字符串[]ExcludeNames{get;set;}
public int MaxPrice{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
var filter=newproductfilter();
filter.MaxPrice=100;
filter.IncludeNames=new[]{“笔记本”,“工作站”};
filter.ExcludeNames=new[]{“路由器”、“调制解调器”};
var query=CreateQueryFromFilter(过滤器);
var client=新的ElasticClient();
//测试序列化
var serialized=Encoding.UTF8.GetString(client.Serializer.Serialize(query));
Console.WriteLine(序列化);
//TODO:如何将IQuery转换为QueryContainer?
//client.Search(s=>s.Query(q=>Query));
}
专用静态IQuery CreateQueryFromFilter(ProductFilter筛选器)
{
var baseBoolean=new BoolQueryDescriptor();
if(filter.IncludeNames!=null&&filter.IncludeNames.Length>0)
{
foreach(变量包含在筛选器中。IncludeNames)
{
//TODO:这将覆盖上一个必须执行的操作
baseBoolean.Must(q=>q.Term(t=>t.Name,include));
}
}
if(filter.ExcludeNames!=null&&filter.ExcludeNames.Length>0)
{
foreach(过滤器中的变量exclude.ExcludeNames)
{
//TODO:这将覆盖上一个必须执行的操作
baseBoolean.MustNot(q=>q.Term(t=>t.Name,exclude));
}
}
如果(filter.MaxPrice>0)
{
//TODO:这将覆盖上一个必须执行的操作
baseBoolean.Must(q=>q.Range(r=>r.lowerequals(filter.MaxPrice).OnField(f=>f.Price));
}
返回baseBoolean;
}
}
}
如您所见,我希望创建某种查询对象(很可能是BoolQuery),然后稍后填充此对象。我已经在代码中添加了一些我遇到实际问题的TODO。但总的来说,有太多的可能性(IQuery、QueryContainer、XXXQueryDescriptor、SearchDescriptor、SearchRequest),我不知道如何成功地一部分一部分地“构建”查询


有谁能给我一些启发吗?

这里的文档中描述了组合布尔查询:

该页面有点过时,将很快更新,尽管大部分页面仍然适用。我更新了您的
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;
}
专用静态IQueryContainer CreateQueryFromFilter(ProductFilter筛选器)
{
QueryContainer QueryContainer=null;
if(filter.IncludeNames!=null&&filter.IncludeNames.Length>0)
{
foreach(变量包含在筛选器中。IncludeNames)
{
//使用对象初始值设定项语法
queryContainer&=newtermquery()
{
Field=Property.Path(p=>p.Name),
值=包括
};
}
}
if(filter.ExcludeNames!=null&&filter.ExcludeNames.Length>0)
{
foreach(过滤器中的变量exclude.ExcludeNames)
{
//使用静态查询分派fluent语法
//注意!这里的支持引入了一个must_not子句
queryContainer&=!Query.Term(p=>p.Name,排除);
}
}
如果(filter.MaxPrice>0)
{
//通过手动更新描述符,语法流畅
queryContainer&=新的QueryDescriptor()
.Range(r=>r.lowerequals(filter.MaxPrice).OnField(f=>f.Price)
);
}
返回查询容器;
}
以下是如何将其传递给搜索操作:

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));
}
static void Main(字符串[]args)
{
//使用对象初始值设定项语法
client.Search(新的SearchRequest()
{
查询=查询
});
//使用流畅的语法
client.Search(s=>s.Query(Query));
}

谢谢!到目前为止还不错。还有没有一种方法可以将“应该”部分添加到查询中,或者我需要将所有“应该”保存在自己的数组中并添加到最后?应该可以使用
=
添加,注意布尔查询不完全遵循代数布尔逻辑!正如这里所解释的,我遇到的一个“gotcha”是
QueryContainer
声明。我有
QueryContainer query=newquerycontainer(),而不是将其设置为
null
。然后使用
|=newtermquery{}
组合术语。这导致一个空的
QueryContainer
,API调用返回“bad request”。我在Nest 2.3.1中找不到
Property.Path
。有人有线索吗?