web-dev-qa-db-ja.com

MongoDB:ネストされたドキュメント内のIDでドキュメントを検索する方法

このようなコレクションが与えられた場合:..

[
  {
    "_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でドキュメントを見つけるにはどうすればよいですか?私はこれを試しました...

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で検索する必要がありますが、ネストされたドキュメント自体は表示されません。

9
j3d

使用 ドット表記

フィールドに埋め込みドキュメントが含まれている場合、クエリでは、埋め込みドキュメントの完全一致を指定するか、ドット表記を使用して埋め込みドキュメントの個々のフィールドによる一致を指定できます。

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

_idがある配列の部分のみを出力する必要がある場合は、使用する必要があります 投影でドル

位置$演算子は、クエリ結果からのコンテンツを制限して、クエリドキュメントに一致する最初の要素のみを含めます。

クエリは次のようになります。

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

P.S。変更した質問のように出力が必要な場合は、次を使用します。

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

$ elemMatch演算子は、クエリ結果のフィールドの内容を制限して、$ elemMatch条件に一致する最初の要素のみを含めます。

あなたの場合:

db.users.find({'_id': ObjectId('5546329a470000850084a621')}, {accounts: {$elemMatch: {_id: ObjectId('5546329a470000850084a655')}}})

参照: Mongo Docs

5
Gaurav Dave

基準で$elemMatchを使用し、以下のようにプロジェクトで$位置演算子を使用します。

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