我有像下面的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或我做错了吗?
答案 0 :(得分:21)
MongoDB查询语言旨在返回所有匹配的文档。
不支持仅返回子文档。
此问题在MongoDB的票证跟踪器中有outstanding ticket。
更新:看起来票证已标记为已修复。
有关如何使用此功能的示例,请参阅here。
答案 1 :(得分:5)
可以使用map / reduce完成,只需将子元素发送到临时内联集合中即可。它是一个Hack而且它可以工作但是我建议反对它,因为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}})
答案 2 :(得分:3)
如果您只想选择匹配元素,可以像这样查询。
b.coll.find({“auther”:“xyz”,“books.book1”:“b1”},{“books。$。date”:1})
答案 3 :(得分:2)
有点想象力( pre mongo v 2.6 )......
您可以使用aggregate或map reduce执行此操作。 Aggregate更新,更简单,更优化。这是一个返回带有聚合的子文档的示例,假设您的集合名为“作者”。我冒昧地拼写了正确的东西。
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')
如果找到了书籍集合,并且只有一个记录,那么你将收到这些书籍:
{ _id: 'xyz', books: [ { book1: 'b1', date: '2-4-00' } ] }