MongoDB在内存map-reduce,native mapReduce还是聚合?

时间:2014-04-02 09:44:23

标签: javascript node.js mongodb aggregation-framework nosql

我有一个名为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作为顶级对象移动会很棒,如上所示。

0 个答案:

没有答案