MongoDB:如何在嵌套文档中根据id查找文档

14

假设有这样一个集合:

[
  {
    "_id" : ObjectId("5546329a470000850084a621"),
    "name": "Joe",
    "surname": "Smith",
    "accounts": [
      {
        "_id" : ObjectId("5546329a470000850084a655"),
        "default": true,
        "status" : "approved",
        "activationTime" : ISODate("2013-05-03T14:37:15.025Z")
      },
      {
        "_id" : ObjectId("5546329a470000850084a688"),
        "default": true,
        "status" : "approved",
        "activationTime" : ISODate("2014-06-03T14:37:15.025Z")
      }
    ]
  },
  {
    "_id" : ObjectId("9546329a470079850084a622"),
    "name": "Jimmy",
    "surname": "Brown",
    "accounts": [
      {
        "_id" : ObjectId("5546329a470790850084a651"),
        "default": true,
        "status" : "suspended",
        "activationTime" : ISODate("2015-02-03T14:37:15.025Z")
      },
      {
        "_id" : ObjectId("5546329a470019850084a611"),
        "default": true,
        "status" : "approved",
        "activationTime" : ISODate("2015-04-03T14:37:15.025Z")
      }
    ]
  },
]

我该如何通过accounts.N._id找到一个文档呢?我试过了以下方法...

...

=>

...

accounts.N._id

and accounts.N._id => accounts.N._id 其他内容不需改变。
db.users.find(
  {},
  {
    "accounts": 0, "accounts": {
      "$elemMatch": { "_id" : ObjectId("5546329a470019850084a611"), "default": true }
    }
  }
)

...但是它不起作用,因为我只得到了所有文档的_id

{ "_id" : ObjectId("5546329a470000850084a621") }
{ "_id" : ObjectId("9546329a470079850084a622") }

我有所遗漏吗?

编辑

实际上我需要的结果是类似这样的:

{
  "_id" : ObjectId("9546329a470079850084a622"),
  "name": "Jimmy",
  "surname": "Brown"
}

例如,我需要按照accounts.N._id查找,但不显示嵌套文档本身。


有没有办法更新同一个对象的状态? - Dhanraj Nimbalkar
3个回答

32

使用点表示法:

当字段包含嵌入文档时,查询可以通过精确匹配嵌入文档或使用点表示法在嵌入文档中的单个字段上进行匹配。

db.coll.find({
   "accounts._id" :ObjectId("5546329a470019850084a611")
})

如果您需要仅输出包含_id的数组部分,则需要在投影中使用美元符号

位置$运算符将查询结果中的一个数组限制为仅包含与查询文档相匹配的第一个元素。

您的查询将如下所示:

db.coll.find({
   "accounts._id" :ObjectId("5546329a470019850084a611")
}, {
   "accounts.$.": 1
})

附言:如果您需要像修改后的问题中那样的输出,请使用以下内容:

db.coll.find({
   "accounts._id" :ObjectId("5546329a470019850084a611")
 }, {
   accounts : 0
 })

也许对某些人有帮助:要将“id”“字符串”转换为“ObjectId”,必须导入“const objectID = require("mongodb").ObjectID”。 - Ezeeroc

7
$elemMatch运算符将一个字段的内容限制在查询结果中只包含与$elemMatch条件匹配的第一个元素。
在您的情况下:
db.users.find({'_id': ObjectId('5546329a470000850084a621')}, {accounts: {$elemMatch: {_id: ObjectId('5546329a470000850084a655')}}})

参考: Mongo文档


它包括示例、描述和链接到所引用页面和词汇表。这样,提出问题的人可以看到其他MongoDB术语。 - Gaurav Dave

2

在查询条件中使用$elemMatch,并在投影中使用$定位操作符,如下所示:

db.users.find({
  "accounts": {
    "$elemMatch": {
      "_id": ObjectId("5546329a470019850084a611"),
      "default": true
    }
  }
}, {
  "accounts.$._id": 1 // "accounts.$": 1 also works
}).pretty()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接