首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查找和匹配多个集合的问题

查找和匹配多个集合的问题
EN

Stack Overflow用户
提问于 2020-01-23 22:16:17
回答 1查看 40关注 0票数 1

在多个阶段中存在聚合和查找问题。问题是我不能在最后一次查找中通过userId匹配。如果我省略了{ $eq: ['$userId', '$$userId'] },它就会正常工作,并与其他条件匹配。但不是通过userid

我尝试将池作为let添加,并在最后阶段将其用作{ $eq: ['$userId', '$$pools.userId'] },但也不起作用。我得到一个空的优惠券数组。

我用下面的查询得到了这个结果。我想我需要以某种方式使用$unwind?但还没有让它发挥作用。有什么建议吗?

总共有三个集合要连接。首先是userModel,它应该包含池,然后池应该包含用户优惠券。

代码语言:javascript
复制
{
   "userId": "5df344a1372f345308dac12a", // Match this usedId with below userId coming from the coupon

   "pools": [
               {
                "_id": "5e1ebbc6cffd4b042fc081ab",
                "eventId": "id999",
                "eventStartTime": "some date",
                "trackName": "tracky",
                "type": "foo bar",
                "coupon": []
               }
            ]
  },

我需要用正确的数据填充优惠券数组(如下所示),其中有一个匹配的userId。

代码语言:javascript
复制
"coupon": [
                {
                    "eventId": "id999",
                    "userId": "5df344a1372f345308dac12a",  // This userId need to match the above one
                    "checked": true,
                    "pool": "a pool",
        }           

poolProject:

代码语言:javascript
复制
const poolProject = {
    eventId: 1,
    eventStartTime: 1,
    trackName: 1,
    type: 1,
  };

用户项目:

代码语言:javascript
复制
const userProjection = {
    _id: {
      $toString: '$_id',
    },
    paper: 1,
    correctBetsLastWeek: 1,
    correctBetsTotal: 1,
    totalScore: 1,
    role: 1,
  };

聚合查询

代码语言:javascript
复制
  const result = await userModel.aggregate([
{ $project: userProjection },
{
  $match: {
    $or: [{ role: 'User' },
      { role: 'SuperUser' }],
  },
},
{ $addFields: { userId: { $toString: '$_id' } } },
{
  $lookup: {
    from: 'pools',
    as: 'pools',
    let: { eventId: '$eventId' },
    pipeline: [
      { $project: poolProject },
      {
        $match: {
          $expr: {
            $in: ['$eventId', eventIds],
          },
        },
      },
      {
        $lookup: {
          from: 'coupons',
          as: 'coupon',
          let: { innerUserId: '$$userId' },
          pipeline: [
            {
              $match: {
                $expr: {
                  $eq: ['$userId', '$$innerUserId'],
                },
              },
            },
          ],
        },
      },
    ],
  },
},
]);

感谢您的任何意见!

编辑:如果我移动第二次查找(优惠券),使他们在相同的“级别”,它的工作,但我希望有它在池中。如果我添加as: 'pools.coupon',在最后一次查找中,它会覆盖lookedup池数据。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-23 22:45:33

当你访问带有$$前缀的字段时,这意味着它们被Mongo定义为“特殊的”系统变量。

我们不知道Mongo的魔力是如何发生的,但是你用相同的名字命名了两个变量,这就像看起来那样导致了冲突。

因此,要么从第一次查找中删除userId: '$userId',因为您甚至不会使用它。

或者重命名或第二次userId: '$userId'一个不同的名称,如innerUserId: '$userId',以避免在访问它时发生冲突。

不过别忘了之后把{ $eq: ['$userId', '$$userId'] }改成{ $eq: ['$userId', '$$innerUserId'] }

编辑:

现在清楚了pools集合中没有字段userId,只需将第二个lookup集合中的变量从:

代码语言:javascript
复制
let: { innerUserId: '$userId' } //userId does not exist in pools.

至:

代码语言:javascript
复制
let: { innerUserId: '$$userId' }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59880638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档