【问题标题】:How can we sort data based on date in mongodb我们如何在 mongodb 中根据日期对数据进行排序
【发布时间】:2020-05-22 10:02:36
【问题描述】:

如何在 MongoDB 中按升序或降序对文档进行排序

const contact = await AtHome.aggregate([
    {
      $project:{
        name:1,
        partnerName:1,
        phone:1,
        email:1,
        city:1,
        guest:1,
        desc:1,
        requestedOn: { $dateToString: { format: "%d-%m-%Y", date: "$createdAt" } },
        weddingDate: { $dateToString: { format: "%d-%m-%Y", date: "$weddingDate" } },
      }
    },
    { $sort : { createdAt : -1 } }
  ]);
  try {
    res.send(contact);
  } catch (err) {
    res.send('INVALID');
  }

我想将 createdAt:1 添加到 $project 对象,但没有奏效。 AtHome.js(架构)

const mongoose = require('mongoose');
const atHomeSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  partnerName: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  phone: {
    type: String,
    required: true
  },
  weddingDate: {
    type: Date,
    required: false
  },
  city: {
    type: String,
    required: true
  },
  guest: {
    type: Number,
    required: true
  },
  desc: {
    type: String,
    required: true
  },
  createdAt:{
    type: Date,
    default: Date.now()
  }
});

module.exports = mongoose.model('AtHome', atHomeSchema);

我添加了 AtHome.js,这是我的架构文件

这是我尝试过但不起作用的方法,我只是得到未排序的文档 请帮我 谢谢你

【问题讨论】:

  • 请发送您的AtHome 架构。
  • createdAt: 1 添加到$project 对象。
  • @MahdiHashemi const atHomeSchema = new mongoose.Schema({ name: { type: String, required: true }, partnerName: { type: String, required: true }, email: { type: String, required: true }, phone: { type: String, required: true }, weddingDate: { type: Date, required: false }, city: { type: String, required: true }, guest: { type: Number, required: true }, desc: { type: String, required: true }, createdAt:{ type: Date, default: Date.now() } });
  • 不要在评论部分发送,更新你的问题。
  • @MahdiHashemi 将 createdAt: 1 添加到 $project 对象。没用

标签: node.js mongodb sorting aggregate


【解决方案1】:

根据Aggregation framework,您必须首先对数据进行排序,然后将其投影到所需的输出。尝试以下查询:

const contact = await AtHome.aggregate([
{ $sort : { createdAt : -1 } },
{ $project: {
        name:1,
        partnerName:1,
        phone:1,
        email:1,
        city:1,
        guest:1,
        desc:1,
        requestedOn: { $dateToString: { format: "%d-%m-%Y", date: "$createdAt" } },
        weddingDate: { $dateToString: { format: "%d-%m-%Y", date: "$weddingDate" } },
      }
    }
  ]);

  try {
    res.send(contact);
  } catch (err) {
    res.send('INVALID');
  }

【讨论】:

    【解决方案2】:

    如上述答案中所述,您需要在项目之前对数据进行排序。我可以在Schema 中看到您正在使用default: Date.now() 作为createdAt,这会将createdAt 的值设置为定义Schema 的时间,因此所有记录都将具有相同的@ 值987654326@ 直到下次重新启动服务器。如果您需要将createdAt 设置为创建记录的时间,您可以改用Date.now

      createdAt:{
        type: Date,
        default: Date.now
      }
    

    【讨论】:

      【解决方案3】:

      您必须在投影中包含createdAt 字段或更改管道阶段的顺序$sort 然后$project

      每个阶段都会在文档通过管道时对其进行转换。在你的第一阶段,你已经过滤掉了createdAt,所以第二阶段没有任何效果。建议在$project 阶段之前使用$sort,以便$sort 阶段可以使用索引。 This will provide better performance

      // sort order 1 -> asc, -1 ->desc    
      await AtHome.aggregate([ {$sort : { createdAt : 1 }} ,{$project : {...}}])
      

      【讨论】:

        【解决方案4】:

        我认为您的第一步应该是了解聚合管道的工作原理。在流水线阶段,数据从一个阶段传递到另一个阶段。在每个阶段,我们都会对数据进行一些修改,并将修改后的数据传递到下一个流水线阶段。

        这里您的第一个阶段是返回您指定的字段的项目:

        然后将该数据传递到排序阶段,由于排序阶段无法在第一阶段的数据中找到 createdAt 字段,因此返回未排序的数据。

        所以添加

        const contact = await AtHome.aggregate([
            {
              $project:{
                name:1,
                partnerName:1,
                phone:1,
                email:1,
                city:1,
                guest:1,
                desc:1,
                requestedOn: { $dateToString: { format: "%d-%m-%Y", date: "$createdAt" } },
                weddingDate: { $dateToString: { format: "%d-%m-%Y", date: "$weddingDate" } },
                createdAt : 1
              }
            },
            { $sort : { createdAt : -1 } }
          ]);
        

        它给出了 createdAt 字段可以使用哪个排序阶段:

        在管道中使用排序作为第一阶段是非常糟糕的主意。如果有数百万条记录,那么查询将非常慢。所以在限制阶段之前但在匹配阶段之后使用排序总是好的(这样我们要排序的文档数量就更少了)。

        对文档中的 createdAt 和 updatedAt 字段使用时间戳选项。

        const schema = Schema({
          //your fields
        }, {
          timestamps: true }
        });
        

        阅读更多:https://mongoosejs.com/docs/guide.html#timestamps

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多