【问题标题】:MongoDB: Project only the items that was queried for in the array?MongoDB:仅投影数组中查询的项目?
【发布时间】:2020-08-31 15:30:09
【问题描述】:

我有一个用户文档,每个用户都有一个对象数组 给定一个item标签数组,我需要找到item数组有item-tag的用户,并返回整个用户对象除了items数组,我只想返回第一个item存在于用于初始查询的tagArray 中的标签。

//user document
 {
    user: 'John',
    items: [ObjectId('ABC'), ObjectId('123') ...]
 }

//item document
{
  _id: ObjectId('ABC'),
  tag: 'some-unique-id'
}, 
{
  _id: ObjectId('DEF'),
  tag: 'some-unique-tag'
}

用户与项目是一对一的关系,项目可能在用户的项目数组中重复。

这是我目前拥有的,它返回整个用户对象,还返回数组中的所有项目。

const tagArray = [ 'some-unique-id', 'some-unique-tag']
items.aggregate([
  { $match: { 'tag': { $in: tagArray } }},
  { $lookup: {
        from: "users",
        localField: "tag",
        foreignField: '_id',
        as: 'userInfo'
       }
  },
  {
     $project: {??}  //<--- I'm pretty sure I'm missing something in the project
])

我现在的结果:

{
 _id: ObjectId('ABC'),
  tag: 'some-unique-id'
  userInfo : [ {user: 'John', items: [ObjectId('ABC'), ObjectId('123') ...] }]
}

我想要达到的目标:

{
 _id: ObjectId('ABC'),
  tag: 'some-unique-id'
  userInfo : [ {user: 'John', items: [ObjectId('ABC')]} ]
}

编辑: 这里有一个类似的问题:Retrieve only the queried element in an object array in MongoDB collection

但是在我的情况下,我需要过滤条件是“tagArray 中的标签之一。

任何建议或指点将不胜感激,谢谢!

【问题讨论】:

  • 这能回答你的问题吗? Retrieve only the queried element in an object array in MongoDB collection 如上所述,您需要使用 $filter 过滤数组以获取所需的对象!
  • 请使用所有需要的信息进行编辑:示例文档、输入和所需的 o/p..
  • @fishcakesAndCoffee 查找结果也可以让您获得多个用户?还是每次都只有一个用户?
  • 这里需要澄清一下:对于带有_id: ObjectId('ABC'), 'some-unique-id' 的项目,您将获得具有ObjectId('ABC') 的项目之一的用户,如果您在查询中包含其他标签,假设@987654333 @。选择_id 的逻辑是什么?如果您想要其中任何一个,为什么不选择当前标签?还是必须排除ObjectId('ABC')
  • @fishcakesAndCoffee 我想,对于项目 ObjectId('ABC'),您正在查找标签中包含 ObjectId('ABC') 的用户。但是当我再次检查时,我看到你正在加入item.taguser._id。在这种情况下,您不是每个项目都只有 1 个用户,因为 user._id 是唯一的吗?

标签: javascript arrays node.js mongodb projection


【解决方案1】:

我不知道我是否理解你需要什么,但我认为这是一个好的开始(也许你可以自己修改):

测试数据:

 // users collection
  [
    {
      user: "John",
      items: [
        ObjectId("5a934e000102030405000002"),
        ObjectId("5a934e000102030405000003")
      ]
    }
  ]  

 // items collection
  [
    {
      _id: ObjectId("5a934e000102030405000002"),
      tag: "some-unique-id"
    },
    {
      _id: ObjectId("5a934e000102030405000009"),
      tag: "some-unique-tag"
    }
  ]
}

查询:

db.users.aggregate([
  {
    $lookup: {
      from: "items",
      localField: "items",
      foreignField: "_id",
      as: "userInfo"
    }
  },
  // create new fields inside the userInfo array
  {
    $project: {
      "userInfo.user": "$user",
      "userInfo.items": "$items",
      "tag": {
        $arrayElemAt: ["$userInfo.tag", 0]
      }
    }
  },
  // filter the userInfo.items field, based on _id field
  // it's important to use $arrayElemAt here 
  {
    $addFields: {
      "userInfo.items": {
        $filter: {
          input: {
            $arrayElemAt: [
              "$userInfo.items",
              0
            ]
          },
          as: "i",
          cond: {   
            $in: [
              "$$i",
              [
                "$_id" 
              ]
            ]
          }
        }
      }
    }
  }
])

结果:

[
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "tag": "some-unique-id",
    "userInfo": [
      {
        "items": [
          ObjectId("5a934e000102030405000002")
        ],
        "user": "John"
      }
    ]
  }
]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2018-02-20
    • 2019-01-13
    相关资源
    最近更新 更多