c# - 使用 NEST 构建静态查询

标签 c# static elasticsearch builder nest

我正在玩弄 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/

相关文章:

elasticsearch - 在elasticsearch中,聚合如何在未存储的字段上工作

c# - 表达式使用参数调用构造函数并设置其值

c# - View Model Locator 的用途是什么?

c# - 如何在静态方法中获取当前类的名称?

java - 在 Java 中使用静态变量和方法的好处

java - ElasticSearch Java API 异步编写

ruby-on-rails - Elasticsearch 仅针对 multi_match 字段上的特定字段进行精确匹配

C# - 试图找到剩余的 EventHandler 以防止控制超出范围

c# - Xamarin PCL库和Sqlite数据存储

php - `static` 函数内部的关键字?