MongoDB:通过_id查询子文档集

时间:2013-03-24 09:09:21

标签: mongodb

收集:

[
{
   tracks: [{_id: 'xxx', title: 'track x'}, {_id: 'yyy', title: 'track y'}
},
{
   tracks: [{_id: 'zzz', title: 'track z'}, {_id: 'ttt', , title: 'track t'}
}
]

我想得到的结果集只包含id为xxx和zzz的曲目:

tracks: [{_id: 'xxx'}, {_id: 'zzz'}

我尝试使用聚合框架:

{$unwind : "$tracks" },
{$match: {'tracks._id': {$in:['xxx', 'zzz']}} }

但它返回空集[]

对我来说奇怪的是,如果我尝试与另一个匹配(字段不是_id),它会起作用

{$unwind : "$tracks" },
{$match: {'tracks.title': {$in:['track x', 'track x']}} }

我如何完成任务?

P.S。我使用mongoose.js框架进行查询。

2 个答案:

答案 0 :(得分:1)

所以我已经找到了问题:要通过_id选择,需要将id值显式地转换为本机ObjectId类型。

var ObjectId = mongoose.Types.ObjectId
...
{$unwind : "$tracks" },
{$match: {'tracks._id': {$in:[ObjectId('5140a09be5c703ac2c000002'), ObjectId('5140a09be5c703ac2c000002')]}} }

我认为这是一个错误,我在mongoose.js repo中创建了一个问题。

UPD。从mongoose.js贡献者那里回答这个问题: 此时,参数不会转换为模式,因为$ project运算符允许在管道的任何阶段重新定义文档的“形状”。 - 返回的文档是普通的javascript对象,而不是转换为此模型架构定义的mongoose文档(因为可以返回任何形状的文档)。

答案 1 :(得分:0)

你的查询没有问题它应该工作(我从未使用过mongoose)。但您可以尝试使用find()进行投影以获得类似的结果:

db.tracks.find(
  { 'tracks._id': { $in: [ 'xxx', 'zzz' ] } }, 
  { _id: 0, 'tracks.title': 0, tracks: { $elemMatch: { _id: { $in: [ 'xxx', 'zzz' ] } } }
)  
相关问题