我有一个名为collections
的集合,其中包含items
的嵌套数组。
{
id: 1,
items: [{id: 'a', val: 1}, {id: 'b', val: 1}, {id: 'c', val: 1}]
},
{
id: 2:
items: [{id: 'b', val: 1}, {id: 'c', val: 1}, {id: 'd', val: 1}]
}
请查看json representation of sample。
我想通过集合的ID(包括父集合信息)创建返回items
数组的查询。我非常天真的记忆中的方法:
var collectionFields = ['title', 'description', 'user', 'userData'];
db.collections.find({_id: {$in: ids}}, function (err, collections) {
if (err) {
return callback(err);
}
var items = collections.map(function (c) {
return c.items && c.items.map(function (i) {
return _.extend(i, {collection: _.pick(c, collectionFields)});
});
});
items = items.reduce(function (memo, items) {
if (items) {
memo = memo.concat(items);
}
return memo;
}, []);
callback(null, {data: items, nextPage: false});
});
所以,它的作用是 - 通过给定的id数组选择所有集合。然后map
每个集合,如果集合中有items
(不一定全部都是)map
个项目,并使用collection
属性扩展每个项目,方法是从集合中选取一些字段document(items data items)。
作为输出,我有类似的东西,
[{ _id: 533bdaf44ad47cde5c000022,
created: Wed Apr 02 2014 12:40:04 GMT+0300 (EEST),
date: Wed Apr 02 2014 12:40:04 GMT+0300 (EEST),
itemId: 7,
user: '1396431604156@tests.com',
userId: 533bdaf44ad47cde5c000019,
collection:
{ title: 'collection',
user: '1396431604156@tests.com',
userData: [Object] } },
{ _id: 533bdaf44ad47cde5c000024,
created: Wed Apr 02 2014 12:40:04 GMT+0300 (EEST),
date: Wed Apr 02 2014 12:40:04 GMT+0300 (EEST),
itemId: 9,
user: '1396431604156@tests.com',
userId: 533bdaf44ad47cde5c000019,
collection:
{ title: 'collection',
user: '1396431604156@tests.com',
userData: [Object] } } ]
但我并不感到高兴。首先,我觉得我以非常低效的方式复制了一些本机功能。其次,将来很难应用其他操作,如分页和排序。
我开始考虑 native MongoDB mapReduce
,但未能获得任何好的Node.js示例。而且,我看到aggregation
可以更好地解决它。
是否可以使用mapReduce / aggregation按ID获取所有集合,采用嵌套的items
数组并生成如上所示的结果?
UPD:我想出了更好的解决方案,
db.collections.aggregate([
{
$match: {_id: {$in: ids}}
},
{
$unwind: '$items'
},
{
$project: { _id: 0, item: '$items', collection: { _id: '$_id', title: '$title', description: '$description'} }
},
], callback);
此查询给出的结果
{ item:
{ _id: 533c3c3b6230140000000023,
created: Wed Apr 02 2014 19:35:07 GMT+0300 (EEST),
date: Wed Apr 02 2014 19:35:07 GMT+0300 (EEST),
itemId: 8,
type: 'stackoverflow',
user: '1396456507643@tests.com',
userId: 533c3c3b6230140000000019 },
collection: { _id: 533c3c3b623014000000001a, title: 'collection' } },
{ item:
{ _id: 533c3c3b6230140000000024,
created: Wed Apr 02 2014 19:35:07 GMT+0300 (EEST),
date: Wed Apr 02 2014 19:35:07 GMT+0300 (EEST),
itemId: 9,
type: 'github',
user: '1396456507643@tests.com',
userId: 533c3c3b6230140000000019 },
collection: { _id: 533c3c3b623014000000001a, title: 'collection' } } ]
我想要的几乎一个,除了将item
作为顶级对象移动会很棒,如上所示。