0

This question is about filtering and count aggregation in elastic search.

I have an index with documents, each document have a topicId, a geoId, and modalityId. These fields are going to be my filters, and could be any combination. Suppose I have this:

topicId1(10), topicId2(10), geoId1(8), geoId(12), modalityId1(20)

With my code if I select topicId1 the result will be:

topicId1(10), topicId2(0), geoId1(X), geoId(X), modalityId1(X)

(X) means I will have X count of document with topidId1 that contain that field.

I need this behavior only if I select by field topic.

topicId1(10), topicId2(10), geoId1(X), geoId(X), modalityId1(X)

In other words, when I filter by any topicId it won´t have any impact on its aggregation (in this case topicId1 and topicId2), but affects all other fields (GeoId and ModaliyId).

This is my code:

public SearchRequest<DocumentDto> Adapt(RequestDto input)
{
    if (input == null) { throw new ArgumentNullException(nameof(input)); }

    TermQuery geoTerm = null;
    TermQuery topicTerm = null;
    TermQuery modalityTerm = null;


    if (input.GeoId > 0)
    {
        geoTerm = new TermQuery { Field = Infer.Field<DocumentDto>(p => p.GeoIds), Value = input.GeoId };
    }

    if (input.TopicId > 0)
    {
        topicTerm = new TermQuery { Field = Infer.Field<DocumentDto>(p => p.TopicIds), Value = input.TopicId };
    }
    
    if (input.ModalityId > 0)
    {
        modalityTerm = new TermQuery { Field = Infer.Field<DocumentDto>(p => p.ModalityIds), Value = input.ModalityId };
    }


    var aggregations = new Dictionary<string, IAggregationContainer>();

    var topicAggregation = new TermsAggregation(nameof(DocumentDto.TopicIds))
    {
        Field = Infer.Field<DocumentDto>(p => p.TopicIds),
        Size = 30
    };

    var geoAggregation = new TermsAggregation(nameof(DocumentDto.GeoIds))
    {
        Field = Infer.Field<DocumentDto>(p => p.GeoIds),
        Size = 30
    };
    
    var modalityAggregation = new TermsAggregation(nameof(DocumentDto.ModalityIds))
    {
        Field = Infer.Field<DocumentDto>(p => p.ModalityIds),
        Size = 30
    };  

    aggregations.Add(nameof(DocumentDto.GeoIds), new AggregationContainer { Filter = geoAggregation });
    aggregations.Add(nameof(DocumentDto.TopicIds), new AggregationContainer { Filter = topicAggregation });
    aggregations.Add(nameof(DocumentDto.ModalityIds), new AggregationContainer { Terms = modalityAggregation });


    MultiMatchQuery query = GetCueWordsQuery(input.CueWords);

    var searchRequest = new SearchRequest<DocumentDto>
    {
        From = searchFrom,
        Size = searchSize,
        Query = new FunctionScoreQuery()
        {
            Query = new BoolQuery
            {
                Must = new QueryContainer[] { query,  geoTerm, topicTerm, modalityTerm},
            }
        },
        Aggregations = aggregations
    };

    return searchRequest;

}

Thank you!

EdwTests
  • 85
  • 6

0 Answers0