Code Monkey home page Code Monkey logo

Comments (5)

Mpdreamz avatar Mpdreamz commented on May 13, 2024

Here's how i am doing it in a current project. This is simplified a tad but hopefully shows you the general direction.

I have a special search query descriptor class to describe my search:

public class SearchQueryDescriptor
{
  public string Query { get; set; }
  public string Sort { get; set; }
  //selected facets
  public Dictionary<string, List<string>> Facets { get; set; }
  public int Page { get; set; }
  public bool UseFacetting { get; set; }

  //some global boolean filters
  public bool OnlyWithImage { get; set; }
  public bool OnlyHighlighted { get; set; }

  public int PageSize { get; set; }

  public SearchQueryDescriptor()
  {
    this.Facets = new Dictionary<string, List<string>>();
    this.Page = 1;
    this.PAgeSize = 10;
  } 
}

then i am building the search dynamically as followed:

var d = searchDescriptor;
var result = this._elasticClient.Search<SomeObject>(s =>
{
  s
   .From(d.Page * d.PageSize)
   .Take(d.PageSize)
   .Highlight(h => h
     .PreTags("<mark>")
     .PostTags("</mark>")
     .OnFields(
       f => f.OnField(a => a.Title).NumberOfFragments(0),
       f => f.OnField(a => a.Description).FragmentSize(450).BoundaryMaxSize(40)
     )
     .Encoder("html")
   );
  if (p.UseFacetting)
  {
    this.SetFacets(d, s);
    this.SetFilterFacets(d, s);
  }
  this.SetSortForSearch(d, s);
  this.CreateQuery(d, s);
  return s;
});

I am setting the facets as followed:

//normal key value facets
private void SetFacets(SearchQueryDescriptor searchDescriptor, SearchDescriptor<SomeObject> s)
{
  s.FacetTerm(t => t.OnField(f => f.CategoryId).Size(20));
  ...
}

//facet filter/query counts
private void SetFilterFacets(SearchQueryDescriptor searchDescriptor, SearchDescriptor<SomeObject> s)
{
  s.FacetFilter("hasimage", ff => ff.Term(f => f.HasImage, "true"));
 ..
}

and the query:

private void CreateQuery(SearchQueryDescriptor searchDescriptor, SearchDescriptor<SomeObject> s)
{
  s.Query(q => q
    .Bool(mq => mq
      .Must(this.GenerateMustQueries(searchDescriptor, s).ToArray())
    )
  );
}

private IEnumerable<Action<QueryDescriptor<SomeObject>>> GenerateMustQueries(
  SearchQueryDescriptor searchDescriptor, SearchDescriptor<SomeObject> s
)
{
  Action<QueryDescriptor<SomeObject>> a = null;
  var query = searchDescriptor.Query;

  if (!string.IsNullOrWhiteSpace(query))
  {
    a = (q) => q
      .QueryString(qs => qs
        .OnFields(new[] { "title^3" })
        .Operator(Operator.and)
        .Query(query)
      );
    yield return a;
  }
  if (searchDescriptor.OnlyWithImage)
  {
    a = (q) => q.Term(f => f.HasImage, "true");
    yield return a;
  }
  if (searchDescriptor.OnlyHighlighted)
  {
    a = (q) => q.Term(f => f.OnlyHighlighted, "true");
    yield return a;
  }
  //selected facets
  if (searchDescriptor.Facets != null)
  {
    foreach (var f in searchDescriptor.Facets)
    {
      foreach (var v in f.Value)
      {
        var key = f.Key;
        var value = v; //C#5.0 anyone ?? 

        a = (q) => q.Term(key, value);
        yield return a;
      }
    }
  }
}

For me this approach works really well.

I am also playing with an alternative syntax using a static and conditional operator overloading to create (nested) boolean queries even easier.

i.e (Query<SomeObject>.Terms(f=>f.field) && Query<SomeObject>.QueryString(f=>...)) || Query<SomeObject>.Term(...)

although you'd get passed the static as argument in a lambda so:

Query(qs=> (qs.Terms(f=>f.field) && qs.QueryString(f=>...)) || qs.Term(...)) would work too.

In most production use cases you would still need to delegate it off the a separate method that does if statements though i imagine.

from elasticsearch-net.

 avatar commented on May 13, 2024

Hi Martijn,

sorry for the delay - this is exactly what I was looking for!
You are a star!

Thanks,
Marek

from elasticsearch-net.

bigerock avatar bigerock commented on May 13, 2024

Since this was (now) 2 years ago, the code is no longer compiling. Martijn, would you be able to update the code so that it reflects the current code base?

from elasticsearch-net.

Mpdreamz avatar Mpdreamz commented on May 13, 2024

Hi @bigerock I'm planning on doing an example application in the foreseeable future that showcases all the cool features of elasticsearch and how to use them from NEST / Elasticsearch.NET.

from elasticsearch-net.

bigerock avatar bigerock commented on May 13, 2024

awesome! thanks. btw, i took a stab at it ...

 public IEnumerable<Func<QueryDescriptor<SomeObject>, BaseQuery>> GenerateMustQueries(
        SearchQueryDescriptor searchDescriptor, 
        SearchDescriptor<SomeObject> s)
    {
        Func<QueryDescriptor<SomeObject>, BaseQuery> a = null;
    ...
    }

from elasticsearch-net.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.