MongoDB 存储和查询价格历史记录

标签 mongodb mongodb-query

我正在处理一组数据,即产品目录。商品数量大约只有 2 万种,而且价格变动很少。也许每月最多 100 次更新。

但是,在这种情况下,价格变化是有趣的事情,我想长期跟踪价格。

我正在尝试找到存储价格数据的最佳方式,以便于查询。

目前它存储在产品文档的数组中。只是价格和时间戳。考虑到数据集较小且相当静态,您将如何设计模型?

另外,还有一个额外的问题,一个过滤器会是什么样子,可以提供当前价格低于前一个价格的产品列表?

示例数据,模型的简化版本:

// Match, current price is lower than previous price

db.TestC.insert({Name: "P1", CurrentPrice: 10.0,  PriceHistory: [{Price: 14.0, Timestamp: ISODate("2019-04-26T07:11:11.939Z")}, {Price: 12.0, Timestamp: ISODate("2019-04-27T07:11:11.939Z")}]})

// No match, price history doesn't exist yet

db.TestC.insert({Name: "P2", CurrentPrice: 10.0, PriceHistory: null})

// No match, previous price was lower than current price

db.TestC.insert({Name: "P3", CurrentPrice: 18.0, PriceHistory: [{Price: 14.0, Timestamp: ISODate("2019-04-26T07:11:11.939Z")}, {Price: 12.0, Timestamp: ISODate("2019-04-27T07:11:11.939Z")}]})

对此进行更多工作后进行编辑:

所以,我终于想出了我所需要的东西,并认为我应该分享,以防它对某人有帮助:

db.TestCollection.aggregate({
    '$project': {
      'Number': 1, 
      'AssortmentKey': 1, 
      'AssortmentName': 1, 
      'NameExtension': 1, 
      'Name': 1, 
      'CurrentPrice': {
        '$arrayElemAt': [
          '$PriceHistory', -1
        ]
      }, 
      'PreviousPrice': {
        '$arrayElemAt': [
          '$PriceHistory', -2
        ]
      }
    }
  }, {
    '$match': {
      '$expr': {
        '$lt': [
          '$CurrentPrice.Price', '$PreviousPrice.Price'
        ]
      }
    }
  })

最佳答案

实际上我会以相同的方式组织文档。请记住,MongoDB 有每个文档 16 MB 的硬限制,这是非常非常高的限制,在这种情况下几乎无法达到,但它仍然存在。

如果您只需要知道当前价格而不需要历史记录,您可以使用投影进行查询,以避免通过网络发送巨大的数组:

db.TestC.find({Name: 'P1'}, {Name, CurrentPrice}});

对于奖励问题,您可以利用聚合框架:

db.TestC.aggregate([
  {
    $project: {
      Name: 1,
      CurrentPrice: 1,
      PreviousPrice: { // remove this key if you don't need to have previous price in the result
        $arrayElemAt: [
          "$PriceHistory",
          0 // depends on whether you store prices by pushing to the end of history array, or to the beginning of it
        ]
      },
      IsCurrentPriceLower: {
        $lt: [
          "$CurrentPrice",
          {
            $arrayElemAt: [
              "$PriceHistory",
              0 // depends on whether you store prices by pushing to the end of history array, or to the beginning of it
            ]
          }
        ]
      }
    },
  },
  {
    $match: {
      IsCurrentPriceLower: true
    }
  }
])

关于MongoDB 存储和查询价格历史记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55878600/

相关文章:

javascript - NodeJS- Bluebird : wait for loop to complete

Javascript Mongoose - 保存后热正确关闭

ruby-on-rails - MongoDB 和 Rails : How to create Index

php - 使用 php 脚本连接 rockat.chat mongo 数据库

mongodb - 将值转换为键 mongodb 聚合

perl - 如何在不对 MongoDB 的 $in 进行硬编码的情况下动态提供列表?

MongoDB 分组+排序不起作用

Java Spring Boot Json 查询在 MongoDb 中使用正则表达式

mongodb - $setUnion 合并来自多个文档 MongoDB 的数组

mongodb - 获取按日期分组的列中不同值的计数 mongodb