Static query building with NEST

I play with Elasticsearch and NEST.

I have some problems understanding various classes and interfaces that can be used to create and create static queries.

Here is a simplified example of what I want to achieve:

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; } } } 

As you can see, I would like to create some kind of query object (most likely, BoolQuery), and then fill this object later. I have added TODOS code to the code where I have real problems. But in general, there are too many possibilities (IQuery, QueryContainer, XXXQueryDescriptor, SearchDescriptor, SearchRequest), and I cannot figure out how to successfully β€œassemble” a part of a query in parts.

Who could enlighten me?

+6
source share
1 answer

An explanation of logical queries is described in the documentation here:

http://nest.azurewebsites.net/nest/writing-queries.html

This page is a bit outdated and will be updated soon, although most of it is still in use. I updated your CreateQueryFromFilter method to demonstrate several ways in which you can formulate queries:

 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; } 

Here you can pass this search operation:

 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)); } 
+18
source

Source: https://habr.com/ru/post/973565/


All Articles