收集:
[
{
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框架进行查询。
答案 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' ] } } }
)