【问题标题】:MongoDB java API aggregate $lookup and pipeline use variableMongoDB java API 聚合 $lookup 和管道使用变量
【发布时间】:2020-08-12 13:06:06
【问题描述】:

我有 2 个集合假设为一对多关系,例如用户和 cmets。要求是将用户与其最新评论合并为单个对象,并返回新合并对象的列表作为结果。

聚合在 mongo 控制台中完美运行

db.user.aggregate(
        {
            $addFields:{
                cId: {$toString: '$_id'},
                user: '$$ROOT'
            }
        },
        {$match: {'invitees': {$elemMatch: {'user.userId': '5e70e82532044a5e4e7cbc8d'}}}},
        {$lookup: {
                from: 'comment',
                let: {'cc': '$cId'},
                pipeline: [
                    {$match: {$expr: {$and: [{$eq: ['$$cc', '$userId']},{$gte: ['$time', '$$NOW']}]}}},
                    {$sort: {'time': -1}},
                    {$limit: 1}
                ],
                as: 'next'
            }
        },
        {$unwind: {path: '$next'}},
        {
            $project: {
                _id: 0,
                user: 1,
                next: 1,
                status: {
                    $map: {
                        input: {
                            $filter: {
                                input: '$invitees',
                                as: 'item',
                                cond: {
                                    $eq: ['$$item.user.userId', '$userId']
                                }
                            }
                        },
                        as: 'invitee',
                        in: '$$invitee.status'
                    }
                }
            }
        },
        {$unwind: {path: '$status'}},
        {$match: {$expr: {$in: ['$status', ['Accepted', 'Pending']]}}},
        {$sort: {status: 1}}
        )

我尝试将其翻译为 spring-data 聚合,但 $toString 出现问题。然后我尝试使用 mongodb java API Aggregations API 来运行它。

Arrays.asList(
        Aggregates.addFields(Arrays.asList(
            new Field<>("cId", Document.parse("{$toString: '$_id'}")),
            new Field<>("user", "$$ROOT"),
            new Field<>("userId", userId)
            )
        ),
        Aggregates.match(Filters.elemMatch("invitees", Filters.eq("user.userId", userId))),
        Aggregates.lookup(
            "comment",
            Collections.singletonList(new Variable<>("cc", "$cId")),
            Arrays.asList(
                Aggregates.match(
                    Filters.expr(
                        Filters.and(
                            Filters.eq("$$cc", "$userId")
                        ))),
                Aggregates.sort(Sorts.ascending("time")),
                Aggregates.limit(1)
            ),
            "next"
        )
    );

    AggregateIterable<Document> r = mongoClient
        .getDatabase("my-db")
        .getCollection("user")
        .aggregate(l);

接收错误:

Command failed with error 168 (InvalidPipelineOperator): 'Unrecognized expression '$$cc'' on server localhost:27017. The full response is {"ok": 0.0, "errmsg": "Unrecognized expression '$$cc'", "code": 168, "codeName": "InvalidPipelineOperator"}

使用:

    <dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>mongodb-driver</artifactId>
      <version>3.12.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mongodb/mongodb-driver-core -->
    <dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>mongodb-driver-core</artifactId>
      <version>3.12.3</version>
    </dependency>


    <dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>bson</artifactId>
      <version>3.12.3</version>
    </dependency>
  • java版本:8
  • mongod 版本:4.2.2
  • mongo shell 版本:4.2.3

非常感谢任何建议。

【问题讨论】:

  • 我也在找这种场景,如果你得到答案,请发帖。如果还有参考,请发帖

标签: java mongodb aggregate


【解决方案1】:

我认为关键是Filters.eq 无法读取以$ 为前缀的变量,例如$$cc$userId。我尝试重写这部分,它可以工作。

Aggregates.match(
    Filters.expr(
        Filters.and(
             new Document("$eq", Arrays.asList("$userId", "$$cc"))
        )
    )
)

【讨论】:

  • 感谢分享。我忘了更新问题。我设法使它与不同的方法一起工作。我的意思是混合 Spring Aggregation、Mongo Java Aggregation SDK 以及 Document.parse 我希望也能发布我的答案
  • @ArthurKazemi。你能发表你的答案吗?
猜你喜欢
  • 2018-08-06
  • 2019-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 2020-08-02
  • 2018-07-07
  • 2021-04-11
相关资源
最近更新 更多