1

I'm pretty new to Elastic Search and the Elastic Search API I'm using in C#: PlainElastic.Net.

I have a simple request, but I'm stuck with it: how can I add multiple (not hardcoded) facets in my querybuiler?

//code has been simplified 

//list of fields I want to be added in my facet part of the querybuilder
List<string> FacetFields = new List<string>{"field1", "field2", "fieldN"};

//qb is already instantiated with a simple ES query 
//I want now to add facets definition

qb.Facets(_facets =>
    FacetFields.ForEach(_ff => 
        _facets.Terms(t => t
           .FacetName("FacetsFor" + _ff)
           .Field(_ff)
        );
    });
);

This does not compile, the error is:

Can not convert lambda expression to delegate type 'System.Func<PlainElastic.Net.Queries.Facets<MyType>,PlainElastic.Net.Queries.Facets<MyType>>', as some return types of block are not implicitly convertible to the return type delegate

Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
oZn3r0L
  • 25
  • 1
  • 5

2 Answers2

0

I'm not a C# guy, but comparing with my Ruby code I think you have things inside out.

The aim is to get the eventual JSON to look something like

"facets" : {
  "facet_name1" : { "terms" : {"field" : "tags"} }
  "facet_name2" : { "terms" : {"field" : "user"} }
}

Looking at your code it looks like your result might be that terms is sitting outside each clause with the facet name inside it. That is not correct if that is what the code is actually doing.

If you have a way to view the JSON produced by your library or the output from elasticsearch after the query, you'll definitely be able to see what the query looks like that ES receives, which I find essential in debugging my own queries.

Inside each named face, you can add additional filtering too, but get the simple case working first, with one facet, then two, then more complex filtering.

Phil
  • 2,797
  • 1
  • 24
  • 30
0

The reason of this compilation error is that the List<T>.ForEach() returns void and qb.Facets() expects result of type Facets<MyType>.

So your code should look like this:

List<string> FacetFields = new List<string>{"field1", "field2", "fieldN"};

qb.Facets(_facets => {
    FacetFields.ForEach(_ffield => 
        _facets.Terms(t => t
           .FacetName("FacetsFor" + _ffield)
           .Field(_ffield)
        )
    );
    // Return configured _facets as expected by qb.Facets
    return _facets;
});

// Get generated JSON
string jsonQuery = qb.BuildBeautified();
ayrov
  • 1