0

收藏:

[
{
   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']}} }

我怎样才能完成我的任务?

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

4

2 回答 2

1

所以我发现了问题:通过 _id 选择需要将 id 值显式转换为原生 ObjectId 类型。

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

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

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

于 2013-03-24T22:51:08.703 回答
0

您的查询没有任何问题,它应该可以正常工作(但是我从未使用过猫鼬)。但是您可以尝试使用find()with projection 来实现类似的结果:

db.tracks.find(
  { 'tracks._id': { $in: [ 'xxx', 'zzz' ] } }, 
  { _id: 0, 'tracks.title': 0, tracks: { $elemMatch: { _id: { $in: [ 'xxx', 'zzz' ] } } }
)  
于 2013-03-24T11:48:51.877 回答