【问题标题】:translate mongo query to spring-data-mongo query将 mongo 查询转换为 spring-data-mongo 查询
【发布时间】:2022-01-17 04:32:05
【问题描述】:

我有一个使用 mongoPlayground here. 制作的查询

db.Workflow.aggregate([
  {
    $match: {}
  },
  {
    $unwind: "$tasks"
  },
  {
    "$addFields": {
      "workflow": "$$ROOT"
    }
  },
  {
    "$project": {
      workflowTask: "$tasks",
      workflow: "$workflow"
    }
  },
  {
    $set: {
      "workflowTask.workflow": "$workflow"
    }
  },
  {
    $unset: [
      "workflowTask.workflow.tasks",
      "workflow",
      "_id"
    ]
  },
  {
    $facet: {
      data: [
        {
          $skip: 0
        },
        {
          $limit: 30
        },
        
      ],
      count: [
        {
          $group: {
            _id: null,
            total: {
              $sum: 1
            }
          }
        },
        
      ],
      
    }
  }
])

我很难将其转换为 spring-data-mongo 聚合对象!

更准确地说:

  • 匹配很好
  • 放松就好了
  • 项目很好

似乎 $$ROOT 变量在 spring-data 中不起作用! 另外,$set 和 $unset 似乎不受支持? 最后,对于方面,我可以生成 data[] 部分,但无法生成计数:{ total: xx}

【问题讨论】:

    标签: mongodb spring-data-mongodb


    【解决方案1】:

    您使用的是哪个版本的 Spring Data MongoDB?在 2.5.0 版本中,每个操作的工作方式如下。

    MatchOperation matchOperation = Aggregation.match(new Criteria());
    UnwindOperation unwindOperation = Aggregation.unwind("tasks");
    AddFieldsOperation addFieldsOperation = Aggregation.addFields().addField("workflow").withValue("$$ROOT").build();
    ProjectionOperation projectionOperation = Aggregation.project("_id").and("tasks").as("workflowTask").and("workflow").as("workflow");
    SetOperation setOperation = SetOperation.builder().set("workflowTask.workflow").toValueOf("workflow");
    UnsetOperation unsetOperation = UnsetOperation.unset("workflowTask.workflow.tasks", "workflow", "_id");
    FacetOperation facetOperation = Aggregation.facet()
            .and(Aggregation.skip(0L), Aggregation.limit(30))
            .as("data")
            .and(Aggregation.group().count().as("total"))
            .as("count");
    

    Set 和 Unset 在 Aggregation 类中不可用,但可以直接使用。

    【讨论】:

      【解决方案2】:

      正如您所观察到的,Spring-Data 不允许定义所有合法的 MongoDB 查询。
      但是,你可以做一个技巧:

      所有 Spring-Data AggregationOperation 实现(MatchOperationAggregationOperation、...)都变为 org.bson.Document
      您需要做的就是使用 MongoDB JSON 查询实现 AggregationOperation

      • 呼叫建设者:new Document("$unwind", "$tasks")
      • 来自 JSON:Document.parse("{\"$unwind\": \"$tasks\"}")

      // Define aggregation pipelines
      List<AggregationOperation> pipeline = new ArrayList<>();
      
      //$addFields
      pipeline.add(Aggregation.addFields().addFieldWithValue("workflow", "$$ROOT").build());
      
      //$unset
      pipeline.add(agg -> new Document("$unset", 
          Arrays.asList(
              "workflowTask.workflow.tasks",
              "workflow",
              "_id")));
      
      //$facet
      pipeline.add(agg -> new Document("$facet", ...))
      

      AggregationOperation

      【讨论】:

        猜你喜欢
        • 2019-12-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-19
        • 1970-01-01
        • 1970-01-01
        • 2017-05-02
        • 1970-01-01
        • 2012-07-21
        相关资源
        最近更新 更多