我如何仅排序从Mongodb聚合返回的字段($ project),同时还使用$ match,$ lookup和$ filter

问题描述 投票:0回答:1

我非常想从这个查询中得到想要的东西...但是现在我想在通知字段上排序

NOTE:这是一种改进:我现在要问如何返回通知字段上的SORT,而我类似的question问如何返回数据一个开始和结束日期,而我的另一个类似的question询问如何返回仅某些字段

注册架构

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const RegisterSchema = new Schema({
    userId: {type: Schema.Types.ObjectId, required: true},
    accessToken: {type:String, required: true, default: null},
})
module.exports = Register = mongoose.model( 'register', RegisterSchema)

这里有一些寄存器数据

[
  {
    "_id": "Reg_1",
    "userId": "User_1",
    "accessToken": "111"
  },
  {
    "_id": "Reg_2",
    "userId": "User_2",
    "accessToken": "222"
  }
]

下一个文档包含通过accessToken与注册架构相关的数据

通知

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const NotificationSchema = new Schema({
    accessToken: {type:String, required: true},
    summaryId: {type:Number, required: true},
    dateCreated: {type: Date, default: Date.now},

    // I don't want these returned in the final results
    dontWantThis1: {type:Number, required: true},
    dontWantThis2: {type:Number, required: true},
})
module.exports = Notification = mongoose.model( 'notification', NotificationSchema)

这里有一些通知数据

[{
    "_id": "N1_1",
    "accessToken": "111",
    "summaryId": 1111,
    "dontWantThis1": 61,
    "dontWantThis2": 62,
    "dateCreated": "2020-04-17T00:00:00.000+00:00" }, 
  {
    "_id": "N2_1",
    "accessToken": "222",
    "summaryId": 2221,
    "dontWantThis1": 71,
    "dontWantThis2": 72,
    "dateCreated": "2020-04-18T00:00:00.000+00:00" },
  {
    "_id": "N1_2",
    "accessToken": "111",
    "summaryId": 1112,
    "dontWantThis1": 611,
    "dontWantThis2": 622,
    "dateCreated": "2020-05-25T00:00:00.000+00:00" },
  {
    "_id": "N2_2",
    "accessToken": "222",
    "summaryId": 2222,
    "dontWantThis1": 711,
    "dontWantThis2": 722,
    "dateCreated": "2020-05-26T00:00:00.000+00:00" }
]

从此开始

此代码返回我想要的所有内容...,但不按日期创建的日期对通知进行sort优先显示,首先显示最新日期。


        // make sure the input dates are REALLY date objects
        // I only want to see notifications for the month of May (in this example)
        var dateStart = new Date('2020-01-01T00:00:00.000+00:00');
        var dateEnd = new Date('2020-05-30T00:00:00.000+00:00');     

        var match = {$match: { userId: mongoose.Types.ObjectId(userId) } };

        var lookup ={
            $lookup:
            {
                from: "my_Notifications",
                localField: "accessToken",
                foreignField: "accessToken",
                as: "notifications"
            }
        };

        var dateCondition = { $and: [
            { $gte: [ "$$item.dateCreated", dateStart ] },
            { $lte: [ "$$item.dateCreated", dateEnd ] }
          ]}  

        var project = {
            $project: {
                notifications: {
                    $filter: {
                    input: "$notifications",
                    as: "item",
                    cond: dateCondition
                    } } }
        };


        var project2 = {
            $project: {
                "_id": 1,
                "userId": 1,
                "accessToken":1,
                "count":{$size:"$notifications"},
                "notifications._id":1,
                "notifications.summaryId": 1,
                "notifications.dateCreated":1,
                "notifications.dateProcessed":1,
            }
        };


        var agg = [
            match,
            lookup,
            project,
            project2,
        ];


        Register.aggregate(agg)
        .then( ..... )

预期结果

我想按最新日期至最早日期对通知进行排序

我想是 $sort: {dateCreated:-1}

NOTE:哪个“ accessToken”是第一个记录都没有关系……只是通知的日期EACH accessToken记录中的>是最早的。

[
  {
    "_id": "Reg_1",
    "accessToken": "111",
    "count": 2,
    "notifications": [
      {
        "_id": "N1_2",
        "dateCreated": ISODate("2020-05-25T00:00:00Z"),
        "summaryId": 1112
      },
      {
        "_id": "N1_1",
        "dateCreated": ISODate("2020-04-17T00:00:00Z"),
        "summaryId": 1111
      }
    ],
    "userId": "User_1"
  },
  {
    "_id": "Reg_2",
    "accessToken": "222",
    "count": 2,
    "notifications": [
      {
        "_id": "N2_2",
        "dateCreated": ISODate("2020-05-26T00:00:00Z"),
        "summaryId": 2222
      },
      {
        "_id": "N2_1",
        "dateCreated": ISODate("2020-04-18T00:00:00Z"),
        "summaryId": 2221
      }
    ],
    "userId": "User_2"
  }
]

尝试1

我认为这就像在管道中添加排序一样简单:


        var sort = {
            $sort: {dateCreated:-1}
        };

        var agg = [
            match,
            lookup,
            project,
            project2,
            sort,
        ];

无效

尝试2

我以为可能是因为我没有使用通知字段?


        var sort = {
            $sort: {
                "notifications.dateCreated":-1, // newest date first !
            }
        };

        var agg = [
            match,
            lookup,
            project,
            project2,
            sort,
        ];

no ..

尝试3

我使用了mongodb playground(来自我的最后一个问题),并进行了排序...确实可行...但是我希望该排序对返回的通知进行排序[[PER注册,] >尝试4

我使用了mongodb playground并放入了排序...不,...似乎不起作用

尝试5

var sort = { $project: { notifications: { $sort: { "notifications.dateCreated":1, } } } }; var agg = [ match, lookup, project, sort, project2, ]; got this error \"Unrecognized expression '$sort'\"
尝试6

我正在尝试这种playground,但寄存器_id在哪里?

尝试6个预期的输出

我期望看到这个:

[ { "_id": "Reg_2", "accessToken": "a_2", "userId": "User_2", "notifications": [ { "_id": "N2_2", "dateCreated": "2020-05-26T00:00:00.000+00:00", "summaryId": 2222 }, { "_id": "N2_1", "dateCreated": "2020-04-18T00:00:00.000+00:00", "summaryId": 2221 } ], "notifications_count": 2 }, { "_id": "Reg_1", "accessToken": "a_1", "userId": "User_1", "notifications": [ { "_id": "N1_2", "dateCreated": "2020-05-25T00:00:00.000+00:00", "summaryId": 1112 }, { "_id": "N1_1", "dateCreated": "2020-04-17T00:00:00.000+00:00", "summaryId": 1111 } ], "notifications_count": 2 } ]

尝试6错误输出

相反,我得到了这个:

[ { "_id": { "accessToken": "a_2", "userId": "User_2" }, "notifications": [ { "_id": "N2_2", "dateCreated": "2020-05-26T00:00:00.000+00:00", "summaryId": 2222 }, { "_id": "N2_1", "dateCreated": "2020-04-18T00:00:00.000+00:00", "summaryId": 2221 } ], "notifications_count": 2 }, { "_id": { "accessToken": "a_1", "userId": "User_1" }, "notifications": [ { "_id": "N1_2", "dateCreated": "2020-05-25T00:00:00.000+00:00", "summaryId": 1112 }, { "_id": "N1_1", "dateCreated": "2020-04-17T00:00:00.000+00:00", "summaryId": 1111 } ], "notifications_count": 2 } ]

谢谢!

我非常想从查询中得到想要的内容...但是现在我想在通知字段上进行排序注意:这是一种改进:我现在正在问如何在通知字段上返回SORT,...

mongodb sorting pipeline aggregation projection
1个回答
0
投票
您可以使用[$ lookup,$ unwind,$ sort和$ group]聚合管道阶段对通知数组的内容进行排序。 Example

db.Register.aggregate([ { $lookup: { from: "my_Notifications", localField: "accessToken", foreignField: "accessToken", as: "notifications" } }, { // cartesian product of array lengths $unwind: "$notifications" }, { $sort: { // Sort the records by created date "notifications.dateCreated": -1 } }, { $group: { "_id": { "accessToken": "$accessToken", "userId": "$userId" }, "notifications": { $push: "$notifications" }, "notifications_count": { $sum: 1 } } } ])

© www.soinside.com 2019 - 2024. All rights reserved.