zoukankan      html  css  js  c++  java
  • Elastic Search 5.x Nest Multiple Queries C#

    I'm using C# with those nuget packeges;

      <package id="Elasticsearch.Net" version="5.2.0" targetFramework="net462" />
      <package id="NEST" version="5.2.0" targetFramework="net462" />
      <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net462" />

    What I want to do here, I want to get "white" items in price range 2000 - 3000. It's a simple request for a search api, am I right ?

    So I wrote a code for this. Here it is;

    private static void Search(IElasticContext elasticContext, string indexName)
        {
            IQueryContainer termQueryContainer = new QueryContainer();
            termQueryContainer.Term = new TermQuery
                                      {
                                          Field = new Field("description"),
                                          Value = "white"
                                      };
    
            IQueryContainer rangeQueryContainer = new QueryContainer();
            rangeQueryContainer.Range = new NumericRangeQuery
                                        {
                                            Field = new Field("price"),
                                            LessThanOrEqualTo = 3000,
                                            GreaterThanOrEqualTo = 2000
                                        };
    
            //Should get 2 items.
    
            SearchRequest<Product> searchRequest = new SearchRequest<Product>(indexName, typeof(Product))
                                                   {
                                                       Size = 10,
                                                       From = 0,
                                                       Query = (QueryContainer) rangeQueryContainer,
                                                       PostFilter = (QueryContainer) termQueryContainer
                                                   };
    
            EsSearchResponse<Product> response = elasticContext.Search<Product>(searchRequest);
    
            Console.WriteLine(response.StatusMessage);
    
            if (response.IsValid)
            {
                foreach (Product product in response.Documents)
                {
                    Console.WriteLine("Id: {0} | Name: {1}", product.Id, product.Name);
                }
            }
        }

    But it doesn't work because request has been successfull but there is no document(s) in the result, but I have. I can see the docs with Sense plugin.

    If I combine two queries, nest will throw exception in runtime ( Says: "QueryContainer can only hold a single query already contains a TermQuery" ). Here it is;

    Nest throws exception

    Also, I can't use fluent api, because I pass the parameters to my repository-like function;

        EsSearchResponse<Product> response = elasticContext.Search<Product>(searchRequest);

    How can I combine two simple queries ( search in description field & price range between 2000-3000 ) in SearchRequest of Nest dll. And what am I doing wrong?

    Answer

    What you're trying to do is form a compound query from two queries, where both queries must be satisfied by a document in order for it to be considered a match. bool query is used to combine queries in this manner, using the must clause to specify both queries must be satisfied. Here's an example, with the object initializer syntax

    var client = new ElasticClient();
    var indexName = "index-name";
    var mustClauses = new List<QueryContainer>();
    
    mustClauses.Add(new TermQuery
    {
        Field = new Field("description"),
        Value = "white"
    });
    
    mustClauses.Add(new NumericRangeQuery
    {
        Field = new Field("price"),
        LessThanOrEqualTo = 3000,
        GreaterThanOrEqualTo = 2000
    });
    
    var searchRequest = new SearchRequest<Product>(indexName)
    {
        Size = 10,
        From = 0,
        Query = new BoolQuery { Must = mustClauses }
    };
    
    var searchResponse = client.Search<Product>(searchRequest);

    With the range query, a document is either a match for the query clause or not, so we can forgo a score being calculated for the query by adding it as a bool query filter clause

    var indexName = "index-name";
    var mustClauses = new List<QueryContainer>();
    var filterClauses = new List<QueryContainer>();
    
    mustClauses.Add(new TermQuery
    {
        Field = new Field("description"),
        Value = "white"
    });
    
    filterClauses.Add(new NumericRangeQuery
    {
        Field = new Field("price"),
        LessThanOrEqualTo = 3000,
        GreaterThanOrEqualTo = 2000
    });
    
    var searchRequest = new SearchRequest<Product>(indexName)
    {
        Size = 10,
        From = 0,
        Query = new BoolQuery 
        { 
            Must = mustClauses,
            Filter = filterClauses
        }
    };
    
    var searchResponse = client.Search<Product>(searchRequest);
  • 相关阅读:
    【BZOJ3309】DZY Loves Math(莫比乌斯反演)
    【CF666E】Forensic Examination(后缀自动机,线段树合并)
    【HDU5730】Shell Necklace(多项式运算,分治FFT)
    【洛谷4389】付公主的背包(生成函数,多项式运算)
    【CF528D】Fuzzy Search(FFT)
    【BZOJ4259】残缺的字符串(FFT)
    【BZOJ4503】两个串(FFT)
    【CF954I】Yet Another String Matching Problem(FFT)
    Java中泛型Class<T>、T与Class<?>、 Object类和Class类、 object.getClass()和Object.class
    H5和原生APP之间的区别
  • 原文地址:https://www.cnblogs.com/a-du/p/7118051.html
Copyright © 2011-2022 走看看