34

Notesという配列ドキュメントが埋め込まれたノートブックコレクションがあります。標本、見本

ドキュメントは次のようになります。

{
"_id" : ObjectId("4f7ee46e08403d063ab0b4f9"),
"name" : "MongoDB",
"notes" : [
            {
              "title" : "Hello MongoDB",
              "content" : "Hello MongoDB"
            },
            {
              "title" : "ReplicaSet MongoDB",
              "content" : "ReplicaSet MongoDB"
            }
         ]
}

「HelloMongoDB」というタイトルのメモだけを知りたい。何をすべきかわからない

クエリになります。誰かが私を助けることができますか?

4

5 に答える 5

88

あなたはmongoバージョンより高い2.2でこれをすることができます

このようなクエリ:

db.coll.find({ 'notes.title': 'Hello MongoDB' }, {'notes.$': 1});

$elemMatchジャスティン・ジェンキンスのように試すことができます

于 2013-07-12T10:37:55.490 に答える
39

古い回答:他の回答を参照してください。


少なくともマップリデュースがなければ、あなたが求めていることが可能だとは思いません。

こちらをご覧ください:MongoDBでの埋め込みドキュメントのフィルタリング

その答えは、データの操作方法に合わせてスキーマを変更することを示唆しています。

「ドット表記」または$elemMatchのいずれかを使用して、「メモのタイトル」が一致する正しいドキュメントを取得できます...

> db.collection.find({ "notes.title" : "Hello MongoDB"}, { "notes.title" : 1"});

また ...

> db.collection.find({ "notes" : { "$elemMatch" : { "title" : "Hello MongoDB"} }});

ただし、一致の原因となった配列要素だけでなく、配列全体が返されます。

また、考えるべきことがあります...現在の設定では、配列内のアイテムに対して操作を実行するのは難しいでしょう。

スキーマを変更しない場合(リンク先の回答が示唆しているように)...必要に応じて簡単に削除できるように、配列の各要素に「ids」を追加することを検討します。

于 2012-04-06T18:19:39.950 に答える
8

これは、MongoDbバージョン3.2以降で集約を使用して実行できます。

クエリ:

db.Notebook.aggregate(
    {
        $project: {
            "notes": {
                $filter: {
                    input: "$notes",
                    as: "note",
                    cond: { 
                        $eq: [ "$$note.title", "Hello MongoDB" ]
                    }
                }
            }
        }
    }
)

結果:

{ 
    "_id" : ObjectId("4f7ee46e08403d063ab0b4f9"), 
    "notes" : [ 
        { 
            "title" : "Hello MongoDB", 
            "content" : "Hello MongoDB" 
        } 
    ] 
}

$$は、変数にアクセスするためにここで使用されます。ここでは、note内に新しく作成された変数にアクセスするために使用しました$filter

$ filter$ eq$$に関する詳細については、公式ドキュメントをご覧ください。

$ filter:指定された条件に基づいて返す配列のサブセットを選択します。条件に一致する要素のみを含む配列を返します。返される要素は元の順序です。

$ eq: 2つの値を比較し、値が等しいかどうかにかかわらずtrue / falseを返します(...)。

$$:変数は任意のBSONタイプのデータを保持できます。変数の値にアクセスするには、変数名の前に二重ドル記号($$)が付いた文字列を使用します。


ノート:

Justin Jenkinの回答は古く、ここでのkopの回答はコレクションから複数のドキュメントを返しません。この集計クエリを使用すると、必要に応じて複数のドキュメントを返すことができます。

私はこれが必要で、誰かを助けるために投稿したかった。

于 2017-08-21T16:46:12.923 に答える
0

$または$elemMatchを使用できます。$演算子と$elemMatch演算子は、条件に基づいて配列から要素のサブセットを射影します。

$ elemMatch射影演算子は、明示的な条件引数を取ります。これにより、クエリにない条件に基づいてプロジェクトを作成できます。

db.collection.find(
    {
        // <expression>
    },
    {
        notes: {
            $elemMatch: {
                title: 'Hello MongoDB'
            }
        },
        name: 1
    }
)

$演算子は、クエリステートメントの条件に基づいて配列要素を射影します。

db.collection.find(
    {
        'notes.title': 'Hello MongoDB'
    },
    {
        'notes.title.$': 1,
         name: 1
    }
)
于 2017-04-12T12:36:11.173 に答える
-3

次のようにクエリを実行できます。

db.coll.find({ 'notes.title': 'Hello MongoDB' });

詳細については、ドキュメントを参照することもできます。

于 2012-04-06T17:33:16.580 に答える