私は以下のようなmongoコレクションを持っています
{
"auther" : "xyz" ,
"location" : "zzz" ,
"books" :
[
{"book1" : "b1" , "date" : 2-3-00} ,
{"book1" : "b2" , "date" : 4-9-00}
]
}
{
"auther" : "pqr",
"location" : "zzz" ,
"books" :
[
{"book1" : "b1" , "date" : 2-4-00}
]
}
本b1と著者xyzの日付のみを取得したい。
私は以下のようなクエリを作成しました
db.coll.find({"auther" : "xyz" , "books.book1" : "b1"} , {"books.date" : 1})
しかし、次のように出力されます
"books" : {"date" : 2-4-00} , "books" : {"date" : 4-9-00}
私は本b1と他のxyzの日付のみを取得したいです。意味のみ"books" : {"date" : 2-4-00}
mongoで可能ですか、何か間違っていますか?
Map/reduceを使用して実行でき、サブ要素を一時的なインラインコレクションに出力するだけです。そのハックとそれは動作しますが、map/reduceはシングルスレッドであり、達成したいことに対して大きなオーバーヘッドがあるため、アプリケーションのサブ要素を抽出する方がはるかに簡単です。
このようなもの...
地図:
m = function() {
this.books.forEach(function(book){
if(book1 == 'b1'){
emit("books", {date: book.date,});
}
});
}
削減:
r = function(key, values) {
return this;
}
クエリ:
db.coll.mapReduce(m、r、{query:{"auther": "xyz"、 "books.book1": "b1"}、out:{inline:1}})
一致する要素のみを選択する場合は、このようにクエリできます。
b.coll.find({"auther": "xyz"、 "books.book1": "b1"}、{"books。$。date":1})
少し想像して(pre mongo v 2.6)...
これは、集約またはマップの縮小を使用して実行できます。集計はより新しく、より簡単で、より最適化されています。コレクションの名前が「Authors」であると仮定して、集約されたサブ文書を返すサンプルを次に示します。綴りの自由を正しく取りました。
Authors.aggregate([
{ $match: { author: 'xyz' } },
{ $unwind: '$books' },
{
$project: {
_id: '$books.book1',
date: '$books.date'
}
},
{ $match: { '$_id' : 'b1' } }
]);
次のような単一のエントリで配列を取得します。
[{ _id: 'b1', date: '2-4-00' }]
そうでない場合、mongo 2.6 +の場合、本当に簡単な方法を実行できます。
Authors.find({
author: 'xyz',
books: { $elemMatch: { book1: 'b1' } }
},'books')
書籍コレクションが見つかった場合にそれを取得し、レコードを1つだけ取得する場所:
{ _id: 'xyz', books: [ { book1: 'b1', date: '2-4-00' } ] }