【问题标题】:Convert mongodb query into Spring data mongodb syntax将 mongodb 查询转换为 Spring 数据 mongodb 语法
【发布时间】:2022-01-31 15:49:43
【问题描述】:

我正在尝试转换此查询 spring data mongo 语法,但遇到 $add 运算符的问题。

{
        "$project":
            {
              
                "nextYear": {
                    "$dateFromParts":
                        {
                            "year": { "$add": [{ "$year": "$today" }, 1] },
                            "month": { "$dayOfMonth": "$joiningDate" },
                            "day": { "$month": "$joiningDate" }

                        }

                }
            }
    }

在没有 $add 的情况下尝试过,它可以工作,但找不到任何关于 $add 的文档。

 aggregationOperations.add(Aggregation.project()                       
                    .and(DateOperators.DateFromParts.dateFromParts()
                            .year(DateOperators.Year(yearOf("today")))
                            .month(dateOf("joiningDate").dayOfMonth())
                            .day(monthOf("joiningDate"))).as("nextYear"));

【问题讨论】:

    标签: mongodb spring-boot spring-data aggregation-framework spring-data-mongodb


    【解决方案1】:

    如果 pipeline 阶段看起来太难或者你不知道如何使用 spring 转换它,尝试使用这种方式

      import org.bson.Document;
      import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
      ...
    
      AggregationOperation project = ctx -> Document.parse("""
             { "$project": {
              
                "nextYear": {
                    "$dateFromParts":
                        {
                            "year": { "$add": [{ "$year": "$today" }, 1] },
                            "month": { "$dayOfMonth": "$joiningDate" },
                            "day": { "$month": "$joiningDate" }
    
                        }
    
                }
            }}
                """);
    
    

    【讨论】:

    • 请分享我可以参考此语法的文档链接。
    • 我手动找到了这种方式,实际上如果你打开任何 AggregationOperation 的实现(例如org.springframework.data.mongodb.core.aggregation.LimitOperation),你会看到它最终会创建代表 Mongo 中一个阶段的 Document,所以 Document.parse 只是转换bson 字符串到文档。
    • 我和我的同龄人讨论过这个问题,根据他们的说法,这是一种过时的做法。我必须找到一种正确的方法来在 spring 数据中转换这个查询
    • 没错,但我可以看到他们可能会将其更改为AggregationOperation#toPipelineStages,因此它不应该过多地破坏现有的使用。目前toPipelineStages 只使用toDocument
    【解决方案2】:

    找到了解决方案(不是通过在 spring 数据中转换这个确切的查询)。

    使用 java.util.Calendar 获取年份值并将值传递给 dateFromParts 年份函数

     Calendar calendar = Calendar.getInstance();
     calendar.setTime(new Date());
    
    
     aggregationOperations.add(Aggregation.project()                       
                        .and(DateOperators.DateFromParts.dateFromParts()
                                .year(calendar.get(Calendar.YEAR) + 1)
                                .month(dateOf("joiningDate").dayOfMonth())
                                .day(monthOf("joiningDate"))).as("nextYear"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 2018-01-08
      • 2020-10-14
      • 2018-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多