I am trying to build a FacetOperation inside a loop in Java, but I am only getting the result of the first operation. Here's my code:
FacetOperation facetOperation = null;
for (int key = 0; key < 2; key++) {
if (facetOperation == null) {
facetOperation = facet(match(ctx -> basicQueryOriginal.getQueryObject()),
project().and(DATA_SOURCE_ID).as("id"),
group("id").count().as("count"),
project("count").andExclude("_id")
).as("Category " + key);
} else {
facetOperation.and(match(ctx -> basicQueryOriginal.getQueryObject()),
project().and(DATA_SOURCE_ID).as("id"),
group("id").count().as("count"),
project("count").andExclude("_id")
).as("Category " + key);
}
}
Aggregation agg = newAggregation(facetOperation);
AggregationResults<Document> groupResults = mongoTemplate.aggregate(agg, "collection", Document.class);
Document facet = groupResults.getMappedResults().get(0);
facet.forEach((key, value) -> {
countDtos.add(new CountDto(key, ((ArrayList) value).size()));
});
The loop is intended to create multiple FacetOperation operations, but when I run the code, I am only getting the result for only Category 0.
I also want to get result of Category 1, I am using MongoDB Java driver and Spring Data MongoDB. Can anyone help me figure out what's wrong with my code?
Additionally, without loop it works as mentioned in following answer Multiple facets. But my need is to achieve this using loop.
Update
Solution suggested by @valijon works for me. Now I have also created a Text Index in collection. I am able to add sorting on this in my basic query and it works fine using this:
basicQuery.fields().projectAs(MongoExpression.create("'$meta' : 'textScore'"), "score");
Document document = new Document("score", MongoExpression.create("'$meta' : 'textScore'").toDocument());
basicQuery.setSortObject(document)
Now when I try to use this basic query in Aggregation. I get following error:
org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 40218 (Location40218): 'query requires text score metadata, but it is not available' on server localhost:27017.
How can I make aggregation to either ignore the text index or make use of $meta?
I have implemented the change suggested by @Valijon and was able to add support for text index in aggregation pipeline.
Here is my final code which works:
FacetOperation facetOperation = null;
for (int key = 0; key < 2; key++) {
if (facetOperation == null) {
facetOperation = facet(match(ctx -> basicQueryOriginal.getQueryObject()),
project().and(DATA_SOURCE_ID).as("id"),
group("id").count().as("count"),
project("count").andExclude("_id")
).as("Category " + key);
} else {
facetOperation = facetOperation.and(match(ctx -> basicQueryOriginal.getQueryObject()),
project().and(DATA_SOURCE_ID).as("id"),
group("id").count().as("count"),
project("count").andExclude("_id")
).as("Category " + key);
}
}
MatchOperation matchOperation = Aggregation.match(
new TextCriteria().matchingAny("[street]").caseSensitive(false)
);
AddFieldsOperation addFieldsOperation = addFields()
.addFieldWithValue("score", new Document("$meta", "textScore")).build();
Aggregation agg = newAggregation(matchOperation, addFieldsOperation, facetOperation);
AggregationResults<Document> groupResults = mongoTemplate.aggregate(agg, "collection", Document.class);
Document facet = groupResults.getMappedResults().get(0);
facet.forEach((key, value) -> {
countDtos.add(new CountDto(key, ((ArrayList) value).size()));
});