MongoDB java API-переменная агрегата $ lookup и использования конвейера - PullRequest
1 голос
/ 28 апреля 2020

У меня есть 2 Коллекции, предполагающие отношение 1 ко многим, например, пользователь и комментарии. Требуется объединить пользователя с последним комментарием как один объект и вернуть список вновь объединенного объекта как результат.

Агрегация отлично работает в консоли mon go

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}}
        )

I попытался перевести это в spring-data Aggregations, но возникли проблемы с $ 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
  • mon go версия оболочки: 4.2.3

любые предложения приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...