I just started using spring data mongodb aggregation query.
fun findRoot(): MarkdownMongoDocument? {
val aggregation = Aggregation.newAggregation(
MarkdownMongoDocument::class.java,
MarkdownMongoRepositoryProperties.findRoot()
)
val results = mongoTemplate.aggregate(aggregation, MarkdownMongoDocument::class.java)
return results.mappedResults[0]
}
MarkdownMongoRepositoryProperties.findRoot()
public static List<AggregationOperation> findRoot() {
List<String> jsons = List.of(
"{ $match: { pid: 0 } }",
"{$graphLookup:{from:\"t_markdown\",startWith:\"$_id\",connectFromField:\"_id\",connectToField:\"pid\",depthField:\"level\",as:\"children\"}}",
"{$unwind:{path:\"$children\",preserveNullAndEmptyArrays:true}}",
"{ $sort: { \"children.level\": -1 } }",
"{$group:{_id:\"$_id\",title:{$first:\"$title\"},path:{$first:\"$path\"},pid:{$first:\"$pid\"},createUserId:{$first:\"$createUserId\"},isDirectory:{$first:\"$isDirectory\"},children:{$push:\"$children\"}}}",
"{$addFields:{children:{$reduce:{input:\"$children\",initialValue:{level:-1,presentChild:[],prevChild:[]},in:{$let:{vars:{prev:{$cond:[{$eq:[\"$$value.level\",\"$$this.level\"]},\"$$value.prevChild\",\"$$value.presentChild\"]},current:{$cond:[{$eq:[\"$$value.level\",\"$$this.level\"]},\"$$value.presentChild\",[]]}},in:{level:\"$$this.level\",prevChild:\"$$prev\",presentChild:{$concatArrays:[\"$$current\",[{$mergeObjects:[\"$$this\",{children:{$filter:{input:\"$$prev\",as:\"e\",cond:{$eq:[\"$$e.pid\",\"$$this._id\"]}}}}]}]]}}}}}}}}",
"{$addFields:{children:\"$children.presentChild\"}}"
);
return jsons.stream().map(Aggregation::stage).toList();
}
As shown above, I did not find a way to directly convert the entire statement into List<AggregationOperation>
, I can only split the entire statement.
Then I want to view the query statement processed by spring data mongodb, but the output log is omitted.
2024-05-16T15:45:07.693+08:00 DEBUG 10204 --- [nio-8080-exec-6] org.mongodb.driver.protocol.command : Command "aggregate" started on database "sage-dev" using a connection with driver-generated ID 3 and server-generated ID 71 to localhost:27017. The request ID is 12 and the operation ID is 11. Command: {"aggregate": "t_markdown", "pipeline": [{"$match": {"pid": 0}}, {"$graphLookup": {"from": "t_markdown", "startWith": "$_id", "connectFromField": "_id", "connectToField": "pid", "depthField": "level", "as": "children"}}, {"$unwind": {"path": "$children", "preserveNullAndEmptyArrays": true}}, {"$sort": {"children.level": -1}}, {"$group": {"_id": "$_id", "title": {"$first": "$title"}, "path": {"$first": "$path"}, "pid": {"$first": "$pid"}, "createUserId": {"$first": "$createUserId"}, "isDirectory": {"$first": "$isDirectory"}, "children": {"$push": "$children"}}}, {"$addFields": {"children": {"$reduce": {"input": "$children", "initialValue": {"level": -1, "presentChild": [], "prevChild": []}, "in": {"$let": {"vars": {"prev": {"$cond": [{"$eq": ["$$value.level", "$$this.level"]}, "$$value.prevChild", "$$value.presentChild"]}, "current": {"$cond": [{"$eq": ["$$value.level", "$$this.level"]}, "$$value.presentChild", []]}}, "in": {"level": "$$this.level", "prevChild": "$$prev", "presentChild" ...
I looked at the code of MongoTemplate
and found the following line of key code, but the method is private and I cannot call it.
Document command = aggregationUtil.createCommand(collectionName, aggregation, context);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Executing aggregation: %s", serializeToJsonSafely(command)));
}
- I don’t want to set up spring’s logs anymore.
- Is there a way for me to use the entire native statement directly?
- How to view the converted statement of spring data mongodb?
Just help me solve one of the 2nd and 3rd questions, thanks.