首页 > 解决方案 > 关于springdata mongodb聚合

问题描述

目前,我有一个问题。可以在mongodb中使用聚合函数查询对应的数据,但是使用springdatamongodb后发现lookup不能使用变量将string转为objectid,请问这个聚合函数应该怎么写

如何在 Spring Data mogodb 中将其写为 mongodb 表达式

  db.getCollection('course').aggregate([{
            $unwind: '$studentIds',
          },
          {
            $lookup: {
              from: 'student',
              let: { stuId: { $toObjectId: '$studentIds' } },
              pipeline: [
                {
                  $match: {
                    $expr: { $eq: [ '$_id', '$$stuId' ] },
                  },
                },
                {
                  $project: {
                    isSendTemplate: 1,
                    openId: 1,
                    stu_name: '$name',
                    stu_id: '$_id',
                  },
                },
              ],
              as: 'student',
            },
          }])

标签: aggregation-frameworkspring-data-mongodb

解决方案


对于复杂和自定义的聚合查询,您可以创建自定义 AggregationOperation,然后从 Mongo shell 传递聚合 json,或者按原样传递。例如:

import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;

public class CustomAggregationOperation implements AggregationOperation {

  private String jsonOperation;

  public CustomAggregationOperation(String jsonOperation) {
    this.jsonOperation = jsonOperation;
  }

  @Override
  public org.bson.Document toDocument(AggregationOperationContext aggregationOperationContext) {
    return aggregationOperationContext.getMappedObject(org.bson.Document.parse(jsonOperation));
  }
}

现在传递$lookup查询,因为它在聚合查询类中的上述类中,如下所示:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.stereotype.Service;
import sample.data.mongo.models.Course;

@Service
public class LookupAggregation {

  @Autowired
  MongoTemplate mongoTemplate;

  public void LookupAggregationExample() {

    AggregationOperation unwind = Aggregation.unwind("studentIds");

    String query1 = "{$lookup: {from: 'student', let: { stuId: { $toObjectId: '$studentIds' } },"
        + "pipeline: [{$match: {$expr: { $eq: [ '$_id', '$$stuId' ] },},}, "
        + "{$project: {isSendTemplate: 1,openId: 1,stu_name: '$name',stu_id: '$_id',},},], "
        + "as: 'student',}, }";

    TypedAggregation<Course> aggregation = Aggregation.newAggregation(
        Course.class,
        unwind,
        new CustomAggregationOperation(query1)
    );

    AggregationResults<Course> results =
        mongoTemplate.aggregate(aggregation, Course.class);
    System.out.println(results.getMappedResults());
  }
}

有关更多详细信息,您可以在以下位置查看我的 Github 存储库:https ://github.com/krishnaitd/learningJava/blob/master/spring-boot-sample-data-mongodb/src/main/java/sample/data/mongo/服务/LookupAggregation.java


推荐阅读