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!