Facet`s feature with NEST and aggregation api

At this moment my UI has 4 groups with searching checkboxes:

1) text input (full text search and exact matches)
2) grades (list of checkboxes)
3) subjects (list of checkboxes)
4) types (list of checkboxes)

Between groups require must condition, between checkboxes in each group should condition.

C# code:

            return new SearchDescriptor<AssignmentDocument>().Index(AssignmentIndex)
                .Query(q => q.Bool(
                            b => b.Filter(
                                f => f.Bool(
                                    b2 => b2.Must(
                                        new BoolQuery { Should = gradesFilters },
                                        new BoolQuery { Should = subjectsFilters },
                                        new BoolQuery { Should = typesFilters }
                                    )
                                )
                            ).Must(SetText(query))
                        )
                    )
                    .From(query.From)
                    .Size(query.Size)
                    .Highlight(SetHighlights(query))
                    .Sort(sort => sort.Descending(doc => doc.CreationDate));
        public async Task<SearchResult> SearchAsync(SearchQuery query)
        {
            var sd = _searchDescriptorProvider.CreateSearchDescriptor(query);
            var response = await _elasticClient.SearchAsync(sd);

            return _mapper.Map<SearchResult>(response);
        }

How can i count finded documents for each checkbox without breaking should/must logic?

Besides following code snippet i have no idea how implement this functionality.

            return new MultiSearchDescriptor().Index(AssignmentIndex)
                    .Search<AssignmentDocument>(
                        "checkbox1_search",

                    //search query for checkbox1 with ValueCount aggregation
                    )
                    .Search<AssignmentDocument>(
                        "checkbox2_search",

                    //search query for checkbox2 with ValueCount aggregation
                    );

Can any suggest more efficient way for write this?

1 Like

By using named queries, you can see which queries matched for a given document in the response with the matched_queries array for each hit.

@forloop

Thank you! Very simple solution. But for counting filters hits, needed following code:

void Main()
{
   var docs = enumerateDocuments()
   	.SelectMany(x => x.MatchedQueries)
   	.GroupBy(x => x)
   	.Select(group => 
   		new 
   		{
   			Metric = group.Key,
   			Count = group.Count() 
   		});
   		
   		
   docs.Dump();
}

public class Document
{
   public int Id  { get; set; }
   
   public string[] MatchedQueries { get; set; }
}

private static IEnumerable<Document> enumerateDocuments()
{
   yield return new Document { Id = 1, MatchedQueries = new [] { "foo", "bar" } };
   yield return new Document { Id = 2, MatchedQueries = new [] { "foo", "baz" } };
   yield return new Document { Id = 3, MatchedQueries = new [] { "foo" } };
   yield return new Document { Id = 4, MatchedQueries = new [] { "bar" } };
   yield return new Document { Id = 5, MatchedQueries = new [] { "baz" } };
   yield return new Document { Id = 6, MatchedQueries = new [] { "bar", "baz" } };
   yield return new Document { Id = 7, MatchedQueries = new [] { "foo", "baz" } };
}

Can i avoid linq usage on server side and aggregate needed metrics on elastic side with aggregation api?

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.