【问题标题】:How to make a lookup of the "Author" field of various arrays in mongodb?如何在mongodb中查找各种数组的“作者”字段?
【发布时间】:2020-07-27 11:45:36
【问题描述】:

我的问题是我想对对象数组“评论”、“关注者”和“观看”的“作者”字段进行查找,但我不知道为什么它在其他对象中给了我这个结果数组,该值与“评论”数组中的文档重复相同的次数。

  .unwind({ path: '$reviews', preserveNullAndEmptyArrays: true })
  .lookup({
    from: 'users',
    let: { userId: '$reviews.author' },
    pipeline: [
      { $match: { $expr: { $eq: ['$_id', '$$userId'] } } },
      {
        $project: {
          name: 1,
          username: 1,
          photo: 1,
          rank: 1,
          'premium.status': 1,
          online: 1,
        },
      },
    ],
    as: 'reviews.author',
  })
  .unwind({ path: '$followers', preserveNullAndEmptyArrays: true })
  .lookup({
    from: 'users',
    let: { userId: '$followers.author' },
    pipeline: [
      { $match: { $expr: { $eq: ['$_id', '$$userId'] } } },
      {
        $project: {
          name: 1,
          username: 1,
          photo: 1,
          rank: 1,
          'premium.status': 1,
          online: 1,
        },
      },
    ],
    as: 'followers.author',
  })
  .unwind({ path: '$watching', preserveNullAndEmptyArrays: true })
  .lookup({
    from: 'users',
    let: { userId: '$watching.author' },
    pipeline: [
      { $match: { $expr: { $eq: ['$_id', '$$userId'] } } },
      {
        $project: {
          name: 1,
          username: 1,
          photo: 1,
          rank: 1,
          'premium.status': 1,
          online: 1,
        },
      },
    ],
    as: 'watching.author',
  })
  .group({
    _id: '$_id',
    data: {
      $first: '$$ROOT',
    },
    reviews: {
      $push: '$reviews',
    },
    followers: {
      $push: '$followers',
    },
    watching: {
      $push: '$watching',
    },
  })

这是“评论”有文档时的结果:

“Followers / Watching”数组在数据库中没有任何内容,但它在这里以这种方式显示,重复该值与评论中的文档数量相同,我不知道会发生什么。

当所有数组都为空时,会发生这种情况:

它一直显示,但我不知道如何修复它。

总而言之,“评论”,“观看”和“关注者”有一个“作者”字段,我想查找观看的作者字段,以及关注者和评论,但我有这些问题.请问我需要帮助。

示例:这是它在数据库中的外观:

非常感谢您。

【问题讨论】:

    标签: mongodb join mongoose mongoose-populate


    【解决方案1】:

    $unwind 阶段为要展开的数组中的每个元素创建一个新文档。每个新文档都将包含文档中所有其他字段的副本。

    如果原始文档看起来像

    {
      _id: "unique",
      Array1:["A","B","C"],
      Array2:["D","E","F"],
    }
    

    展开“Array1”后,管道中将有3个文档:

    [
     {
       _id: "unique",
       Array1:"A",
       Array2:["D","E","F"]
     },{
       _id: "unique",
       Array1:"B",
       Array2:["D","E","F"]
     },{
       _id: "unique",
       Array1:"C",
       Array2:["D","E","F"]
     }
    ]
    

    然后展开“观察者”将展开 每个 观察者数组,以便您获得数组的笛卡尔积。 Playground

    在您的情况下,原始文档有 2 条评论,但没有关注者和观察者,因此在管道开始时包含一个文档,类似于:

    [
      {
        _id: "ObjectId",
        data: "other data"
        reviews: [{content:"review1", author:"ObjectId"},
                  {content:"review2", author:"ObjectId"}]
      }
    ]
    

    第一次展开后,您有 2 个文档:

    [
      {
        _id: "ObjectId",
        data: "other data"
        reviews: {content:"review1", author:"ObjectId"}
      },
    {
        _id: "ObjectId",
        data: "other data"
        reviews: {content:"review2", author:"ObjectId"}
      }
    ]
    

    第一次查找将作者 ID 替换为每个文档的数据,然后第二次展开应用于每个文档。

    由于该数组为空,因此查找返回一个空数组,并应用第三次展开。 在 $group 阶段之前,管道包含 2 个带有数组的文档:

    [
      {
        _id: "ObjectId",
        data: "other data"
        reviews: {content:"review1", author:"ObjectId"},
        followers: {author: []},
        watchers: {author: []}
      },
    {
        _id: "ObjectId",
        data: "other data"
        reviews: {content:"review2", author:"ObjectId"},
        followers: {author:[]},
        watchers: {author: []}
      }
    ]
    

    由于两个文档具有相同的_id,它们被组合在一起,最终结果包含第一个文档作为“数据”。

    对于数组,当遇到每个文档时,将对应字段的值推送到数组上,导致每个数组有 2 个值。

    【讨论】:

    • 能否请您更正我的代码并能够达到预期的结果?
    • 为避免构建笛卡尔积,请在填充每个数组后重新组合。
    猜你喜欢
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    相关资源
    最近更新 更多