Node + Mongodb + 排序嵌套数组 [英] Node + Mongodb + sort nested array

查看:59
本文介绍了Node + Mongodb + 排序嵌套数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 mongodb 的节点.我尝试对嵌套数组进行排序.

monogodb 中的 json 示例.

<代码>{项目": [{"name": "A",订单":3}, {"name": "B",订单":2}, {"name": "C",订单":1}, {"name": "D",订单":4}],"name": "测试",_id":01245678913}{项目": [{"name": "A",订单":3}, {"name": "B",订单":2}, {"name": "C",订单":1}, {"name": "D",订单":4}],"name": "测试",_id":098765432134}

我希望结果应根据顺序显示.items.order

这里可以传递ID.如果 get Id 表示显示相应 Id 的结果.否则需要显示所有列表.

我附上了我的节点代码:

router.post('/get', function(req, res, next) {变量结果 = {回复:{},id:空,询问 : {}};if (!( typeof req.body['id'] === 'undefined' || req.body['id'] === null )) {结果.id = req.body['id'];}Q(results).then(function(results) {var deferred = Q.defer();var 集合 = mongoUtil.list;如果(results.id!= null){results.query._id = ObjectId(results.id);}collection.find(results.query).toArray(function(err,lists){如果 (!err &&list.length > 0) {results.resp.lists = 列表;deferred.resolve(结果);} 别的 {results.resp.message = '没有列表';results.resp.debug = 错误;deferred.reject(results);}});返回 deferred.promise;}).then(函数(结果){results.resp.message = '找到结果';results.resp.status = '成功';res.send(results.resp);}).失败(功能(结果){results.resp.status = '错误';res.send(results.resp);});});

我发现他们使用聚合函数的例子很少.

collection.aggregate([{$unwind: "$answers"},{$sort: {"item.order":1}},{$group: {_id:"$_id", 答案: {$push:"$answers"}}}]);

这里有点混乱.

解决方案

聚合 操作处理数据记录并返回计算结果.聚合操作将来自多个文档的值组合在一起,并且可以对分组的数据执行各种操作以返回单个结果.

试试这个 -

collection.aggregate([{ $unwind: "$items" },{ $sort: { "items.order": 1 } },{ $group: { _id: "$_id", items: { $push: "$items" } } }]);

<块引用>

db.collection.aggregate(pipeline, options):- 计算集合中数据的聚合值.

Pipeline $unwind (aggregation) stage:- 从输入文档中解构一个数组字段,为每个元素输出一个文档.每个输出文档都是具有数组值的输入文档字段被元素替换.

<块引用>

示例-

考虑具有以下文档的库存项目:

{ "_id" : 1, "item" : "ABC1", 尺寸: [ "S", "M", "L"] }

以下聚合使用 $unwind 阶段输出文档对于sizes数组中的每个元素:

<块引用>

db.items.aggregate( [ { $unwind : "$sizes" } ] )

操作返回以下结果:

{ "_id" : 1, "item" : "ABC1", "sizes" : "S" } { "_id" : 1, "item" :"ABC1", "sizes" : "M" } { "_id" : 1, "item" : "ABC1", "sizes" : "L" }

Pipeline $sort (aggregation) stage:- 对所有输入文档进行排序并按排序顺序将它们返回到管道.

$sort 阶段具有以下原型形式:

{ $sort: { : , : ... } }

<块引用>

示例-

对于要排序的一个或多个字段,将排序顺序设置为 1 或 -1 以分别指定升序或降序排序,如下面的例子:

db.users.aggregate( [{ $sort : { age : -1, posts: 1 } } ] )

Pipeline $group (aggregation) stage:- 将文档分组指定的表达式并为下一个阶段输出一个文档不同的分组.输出文档包含一个 _id 字段,该字段按键包含不同的组.$group 不对其输出进行排序文件.

$group 阶段的原型形式如下:

{ $group: { _id: <expression>, <field1>: { <accumulator1>:<表达式1>}, ... } }

<块引用><块引用>

Accumulator $push:- 返回一个包含所有结果的数组将表达式应用于一组文档中的每个文档按键共享同一个组.

$push 的语法如下:

{ $push: <表达式>}

$push 仅在 $group 阶段可用.

有关更多参考,请参阅此链接 - https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/

I am using node with mongodb.I try to sort nested array.

Example json in monogodb.

{
    "items": [
        {
            "name": "A",
            "order": 3
        }, {
            "name": "B",
            "order": 2
        }, {
            "name": "C",
            "order": 1
        }, {
            "name": "D",
            "order": 4
        }
    ],
    "name": "Test",
        "_id" : 01245678913
}
{
    "items": [
        {
            "name": "A",
            "order": 3
        }, {
            "name": "B",
            "order": 2
        }, {
            "name": "C",
            "order": 1
        }, {
            "name": "D",
            "order": 4
        }
    ],
    "name": "Test",
        "_id" : 098765432134
}

I am expecting result should display based on order. items.order

Here possible to pass ID. If get Id means display the result for the respective Id. otherwise need to show all lists.

I attached my node code:

router.post('/get', function(req, res, next) {

        var results = {
            resp : {},
            id : null,
            query : {}
        };

        if (!( typeof req.body['id'] === 'undefined' || req.body['id'] === null )) {
            results.id = req.body['id'];
        }

        Q(results).then(function(results) {
            var deferred = Q.defer();
            var collection = mongoUtil.list;
            if (results.id != null) {
                results.query._id = ObjectId(results.id);
            }


            collection.find(results.query).toArray(function(err, lists) {

                if (!err && lists.length > 0) {
                    results.resp.lists = lists;
                    deferred.resolve(results);
                } else {

                    results.resp.message = 'No List';
                    results.resp.debug = err;
                    deferred.reject(results);
                }
            });
            return deferred.promise;
        }).then(function(results) {
            results.resp.message = 'Result found';
            results.resp.status = 'Success';
            res.send(results.resp);
        }).fail(function(results) {
            results.resp.status = 'Error';
            res.send(results.resp);
        });

    });

I found few example they using aggregate function.

collection.aggregate([
  {$unwind: "$answers"}, 
  {$sort: {"item.order":1}}, 
  {$group: {_id:"$_id", answers: {$push:"$answers"}}}
]);

Here little bit confusing.

解决方案

Aggregations operations process data records and return computed results. Aggregation operations group values from multiple documents together, and can perform a variety of operations on the grouped data to return a single result.

Try this -

collection.aggregate([
  { $unwind: "$items" },
  { $sort: { "items.order": 1 } },
  { $group: { _id: "$_id", items: { $push: "$items" } } }
]);

db.collection.aggregate(pipeline, options):- Calculates aggregate values for the data in a collection.

Pipeline $unwind (aggregation) stage:- Deconstructs an array field from the input documents to output a document for each element. Each output document is the input document with the value of the array field replaced by the element.

Examples-

Consider an inventory items with the following document:

{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }

The following aggregation uses the $unwind stage to output a document for each element in the sizes array:

db.items.aggregate( [ { $unwind : "$sizes" } ] )

The operation returns the following results:

{ "_id" : 1, "item" : "ABC1", "sizes" : "S" } { "_id" : 1, "item" : "ABC1", "sizes" : "M" } { "_id" : 1, "item" : "ABC1", "sizes" : "L" }

Pipeline $sort (aggregation) stage:- Sorts all input documents and returns them to the pipeline in sorted order.

The $sort stage has the following prototype form:

{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }

Examples-

For the field or fields to sort by, set the sort order to 1 or -1 to specify an ascending or descending sort respectively, as in the following example:

db.users.aggregate( [ { $sort : { age : -1, posts: 1 } } ] )

Pipeline $group (aggregation) stage:- Groups documents by some specified expression and outputs to the next stage a document for each distinct grouping. The output documents contain an _id field which contains the distinct group by key. $group does not order its output documents.

The $group stage has the following prototype form:

{ $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }

Accumulator $push:- Returns an array of all values that result from applying an expression to each document in a group of documents that share the same group by key.

$push has the following syntax:

{ $push: <expression> }

$push is only available in the $group stage.

For more reference see this link - https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/

这篇关于Node + Mongodb + 排序嵌套数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆