【问题标题】:mongodb: how to make selectionmongodb:如何进行选择
【发布时间】:2019-10-22 10:43:14
【问题描述】:

我有一个带有这样对象的 mongodb:

{
    "_id" : "7XXXXXXXXXX",
    "apps" : [ 
        {
            "id" : "e0d538e0df9a345e",
            "os" : "android",
            "token" : "f1zp-VSi7Ec:APA91bEAbfH8nMeVidkIjPrJ28WHRFDy-BhvKCQdDSdCYsylUzET9GjbPHjofCrr1NMQurinMCI4fuiF7VWNPXne-80op_h0MloK217kc1zKptdo9FTgAH5R932uDphcyB1xQ27-AFdR",
            "version" : "3.2.1",
            "build" : "8115680e",
            "timestamp" : NumberLong(1571740696818)
        }
    ]
}

在我的情况下,我如何使用时间戳选择较早的某个日期的对象,例如较早的 3 个月?

【问题讨论】:

标签: mongodb timestamp


【解决方案1】:

您可以在聚合中使用$toDate操作符来做想要的操作,

希望你使用的是 mongo 4.0+ 版本

mongo 4.0 及更高版本支持 $toDate

let selectedDate = new Date();
selectedDate.setDate(d.getDate()-30); //subtracting 30 days from today's date

db.collection("your_collection_name").aggregate({$unwind:{ path: "$apps"}},
    {$addFields: { dateValue: {$toDate: "$apps.timestamp" }}}, 
    {$match: { dateValue: {$lte: selectedDate }}},
    (err, result) => {
       //perform your desired operations
    });

说明:

基本上,我首先展开apps 数组,这将导致apps 中的每个条目都有一个单独的文档。

然后对每个文档中的timestamp字段进行操作,用$toDate转换成合适的日期。

然后在下一阶段使用$match 应用您的过滤器。

更新(来自 cmets):

由于您使用的是 mongo 3.2 版,因此上述解决方案将不起作用。

那么我想,你可以在这里选择另一种方法:

  1. 查询此特定集合中的所有文档,timestamp 字段中找到正确的日期

  2. 更新每个文档,添加一个新字段,该字段现在具有上述步骤中计算出的日期值,然后保存。

  3. 建议你为以上两个步骤写一个迁移脚本

  4. 确保插入新文档时,您已经添加了这个新计算的日期字段。

  5. 然后您可以进行简单的查询,例如:

    db.collection("your_collection_name").find({"app.newDateField": {$lte: {selectedDate }}}, 
        { "apps.$": 1}, 
        (err, result)=>{
    
        })
    

【讨论】:

  • 执行脚本失败。我使用 mongo 3.2.0,当我尝试运行此脚本时出现此错误:错误:TypeError:重新声明 let selectedDate 详细信息:@(shell):1:5
  • 在 mongo 3.2.0 上是否有办法做到这一点?
  • 很遗憾,这是生产数据库,我无法更改或添加任何字段
  • 这里有几个选项...1.您从时间戳中添加一个新字段并将其用于计算。
  • 2. 您更新每个文档并将timestamp 更改为仅包含 ISO 格式的日期。然后有一个简单的查询,如上图所示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-14
  • 2014-11-30
  • 2021-06-02
  • 1970-01-01
相关资源
最近更新 更多