Node.js 使用mm dd yyyy格式在mongodb中排序日期

Node.js 使用mm dd yyyy格式在mongodb中排序日期,node.js,angularjs,mongodb,mean-stack,Node.js,Angularjs,Mongodb,Mean Stack,这是我的示例文档: Bloodrequest.aggregate([{$group: {_id : "$date_claimed" , count:{$sum:1}}},{$sort: {_id: 1}}] console.log(date2); [ { _id: '01-01-2019', count: 1 }, //this should be the most bottom { _id: '01-14-2018', count: 1 }, { _id: '01-20-2018',

这是我的示例文档:

Bloodrequest.aggregate([{$group: {_id : "$date_claimed" , count:{$sum:1}}},{$sort: {_id: 1}}]
console.log(date2);
[ { _id: '01-01-2019', count: 1 }, //this should be the most bottom
  { _id: '01-14-2018', count: 1 },
  { _id: '01-20-2018', count: 1 },
  { _id: '02-13-2018', count: 2 },
  { _id: '03-13-2018', count: 3 },
  { _id: '04-25-2018', count: 1 }]
我正在尝试按升序对我的
日期进行排序,它使用2018年作为年底正常工作,但在我输入2019年的值后,它没有按照顺序进行排序。我怎样才能解决这个问题?我应该遵循
mm dd yyyy
格式

代码:

Bloodrequest.aggregate([{$group: {_id : "$date_claimed" , count:{$sum:1}}},{$sort: {_id: 1}}]
console.log(date2);
[ { _id: '01-01-2019', count: 1 }, //this should be the most bottom
  { _id: '01-14-2018', count: 1 },
  { _id: '01-20-2018', count: 1 },
  { _id: '02-13-2018', count: 2 },
  { _id: '03-13-2018', count: 3 },
  { _id: '04-25-2018', count: 1 }]
收益率:

Bloodrequest.aggregate([{$group: {_id : "$date_claimed" , count:{$sum:1}}},{$sort: {_id: 1}}]
console.log(date2);
[ { _id: '01-01-2019', count: 1 }, //this should be the most bottom
  { _id: '01-14-2018', count: 1 },
  { _id: '01-20-2018', count: 1 },
  { _id: '02-13-2018', count: 2 },
  { _id: '03-13-2018', count: 3 },
  { _id: '04-25-2018', count: 1 }]
使用将日期转换为毫秒并使用.sort()进行排序 我想这是你最好的选择。也许是这样的:

date2.map(res => {
let timeInMs = moment(res._id).unix() //gives you time in seconds
/* */
}).sort()
使用将日期转换为毫秒并使用.sort()进行排序 我想这是你最好的选择。也许是这样的:

date2.map(res => {
let timeInMs = moment(res._id).unix() //gives you time in seconds
/* */
}).sort()

请尝试以下操作:

Bloodrequest.aggregate([
              {
                   $group: {
                         _id :{
                                "day": { "$dayOfMonth" : "$date_claimed" },
                                "month": { "$month" : "$date_claimed" },
                                "year": { "$year" : "$date_claimed"}
                         } , 
                         count:{$sum:1}
                   }
              },
              {
                   $sort: {
                      "_id.year": 1,
                      "_id.month": 1,
                      "_id.day": 1 
                   }
              }
          ]

请尝试以下操作:

Bloodrequest.aggregate([
              {
                   $group: {
                         _id :{
                                "day": { "$dayOfMonth" : "$date_claimed" },
                                "month": { "$month" : "$date_claimed" },
                                "year": { "$year" : "$date_claimed"}
                         } , 
                         count:{$sum:1}
                   }
              },
              {
                   $sort: {
                      "_id.year": 1,
                      "_id.month": 1,
                      "_id.day": 1 
                   }
              }
          ]

由于
mm dd yyyy
不是自然可排序的,因此基于此字段内容的任何解决方案都需要完整集合扫描和/或完整集合操作才能做到这一点,因为您本质上需要对字符串字段使用自定义排序方法

这将是一个主要的性能杀手,从长远来看是不现实的

我建议您将您的
date\u
字段存储到适当的
ISODate()
格式中,在其上放置索引以进行排序,并将
$project
(或类似方法)转换为所需的
mm dd yyyy
格式以进行输出

例如,如果文档的结构如下所示:

> db.test.find()
{
  "_id": 0,
  "date_claimed": ISODate("2018-01-01T00:00:00Z")
}
{
  "_id": 1,
  "date_claimed": ISODate("2018-01-02T00:00:00Z")
}
{
  "_id": 2,
  "date_claimed": ISODate("2019-01-01T00:00:00Z")
}
然后,您可以在
date\u索赔
字段上创建索引:

> db.test.createIndex({date_claimed:1})
您可以按预期的降序显示已排序的日期:

> db.test.aggregate([ {$sort: {date_claimed: -1}} ])
{ "_id": 2, "date_claimed": ISODate("2019-01-01T00:00:00Z") }
{ "_id": 1, "date_claimed": ISODate("2018-01-02T00:00:00Z") }
{ "_id": 0, "date_claimed": ISODate("2018-01-01T00:00:00Z") }
您还可以根据需要使用
$project
mm dd yyyy
格式显示日期。请注意,文档已正确排序:

> db.test.aggregate([ 
    {$sort: {date_claimed: -1}}, 
    {$project: {date_string: {$dateToString: {format: '%m-%d-%Y', date:'$date_claimed'}}}} 
])
{ "_id": 2, "date_string": "01-01-2019" }
{ "_id": 1, "date_string": "01-02-2018" }
{ "_id": 0, "date_string": "01-01-2018" }
有关更多信息,请参阅和手册页

这种方法有两个好处:

  • 您可以在日期字段上放置索引,这样就不必对整个集合执行特殊操作
  • 通过使用
    ISODate()
    字段类型,现在可以使用整个字段

  • 由于
    mm dd yyyy
    不是自然可排序的,因此基于此字段内容的任何解决方案都需要完整集合扫描和/或完整集合操作才能做到这一点,因为您本质上需要对字符串字段使用自定义排序方法

    这将是一个主要的性能杀手,从长远来看是不现实的

    我建议您将您的
    date\u
    字段存储到适当的
    ISODate()
    格式中,在其上放置索引以进行排序,并将
    $project
    (或类似方法)转换为所需的
    mm dd yyyy
    格式以进行输出

    例如,如果文档的结构如下所示:

    > db.test.find()
    {
      "_id": 0,
      "date_claimed": ISODate("2018-01-01T00:00:00Z")
    }
    {
      "_id": 1,
      "date_claimed": ISODate("2018-01-02T00:00:00Z")
    }
    {
      "_id": 2,
      "date_claimed": ISODate("2019-01-01T00:00:00Z")
    }
    
    然后,您可以在
    date\u索赔
    字段上创建索引:

    > db.test.createIndex({date_claimed:1})
    
    您可以按预期的降序显示已排序的日期:

    > db.test.aggregate([ {$sort: {date_claimed: -1}} ])
    { "_id": 2, "date_claimed": ISODate("2019-01-01T00:00:00Z") }
    { "_id": 1, "date_claimed": ISODate("2018-01-02T00:00:00Z") }
    { "_id": 0, "date_claimed": ISODate("2018-01-01T00:00:00Z") }
    
    您还可以根据需要使用
    $project
    mm dd yyyy
    格式显示日期。请注意,文档已正确排序:

    > db.test.aggregate([ 
        {$sort: {date_claimed: -1}}, 
        {$project: {date_string: {$dateToString: {format: '%m-%d-%Y', date:'$date_claimed'}}}} 
    ])
    { "_id": 2, "date_string": "01-01-2019" }
    { "_id": 1, "date_string": "01-02-2018" }
    { "_id": 0, "date_string": "01-01-2018" }
    
    有关更多信息,请参阅和手册页

    这种方法有两个好处:

  • 您可以在日期字段上放置索引,这样就不必对整个集合执行特殊操作
  • 通过使用
    ISODate()
    字段类型,现在可以使用整个字段
  • 凯文的是理想的解决方案。但如果由于任何原因无法更改架构,则可以使用以下解决方案:

    Bloodrequest.dates.aggregate([
      {
        $group: { _id: "$date_claimed", count: { $sum: 1 } }
      },
      {
        $addFields: {
          date: {
            $dateFromString: {
              dateString: "$_id",
              format: "%m-%d-%Y"
            }
          }
        }
      },
      {
        $sort:
          { date: 1 }
      }
    ])
    
    正如凯文所强调的,这是一个性能杀手。仅当数据量较小和/或使用此查询的频率非常低时才应使用。Kevin's是理想的解决方案。但如果由于任何原因无法更改架构,则可以使用以下解决方案:

    Bloodrequest.dates.aggregate([
      {
        $group: { _id: "$date_claimed", count: { $sum: 1 } }
      },
      {
        $addFields: {
          date: {
            $dateFromString: {
              dateString: "$_id",
              format: "%m-%d-%Y"
            }
          }
        }
      },
      {
        $sort:
          { date: 1 }
      }
    ])
    

    正如凯文所强调的,这是一个性能杀手。应仅在数据量较小和/或使用此查询的频率非常低时使用。

    %Y%m%d
    格式将解决此问题。或者您可以
    $dateFromString
    和订单文档
    %Y%m%d
    格式将解决此问题。或者您可以
    $dateFromString
    和订购文档