【问题标题】:MongoDB unique time series data pointMongoDB独特的时间序列数据点
【发布时间】:2021-08-14 18:36:33
【问题描述】:

tl;博士

如何最好地管理时间序列增量文档的安全插入?在数据库端强制执行:代码可能会中断和checking documents already in the DB takes long。我是否应该考虑更改架构(我需要执行时间切片查询)?

细节

我有一个时间序列中的股票价格(这里用 TS 集合建模):

# mongosh
db.stocks.insertMany([{
   "metadata": [{"instrumentId": 5578}, {"FX": "USD"}],
   "timestamp": ISODate("2021-05-18T00:00:00.000Z"),
   "price": 12.5
}, {
   "metadata": [{"instrumentId": 5578}, {"FX": "USD"}],
   "timestamp": ISODate("2021-05-18T04:00:00.000Z"),
   "price": 11.4
}])

假设我将它反序列化为一个对象,添加今天的价格并将其序列化回来。我现在有

# to handle with pymongo
documents = [{
   "metadata": [{"instrumentId": 5578}, {"FX": "USD"}],
   "timestamp": ISODate("2021-05-18T00:00:00.000Z"),
   "price": 12.5
}, {
   "metadata": [{"instrumentId": 5578}, {"FX": "USD"}],
   "timestamp": ISODate("2021-05-18T04:00:00.000Z"),
   "price": 11.4
}, {
   "metadata": [{"instrumentId": 5578}, {"FX": "USD"}],
   "timestamp": ISODate("2021-05-18T08:00:00.000Z"),
   "price": 11.1
}]

选项 1:唯一复合索引

我将它们全部插入 (reversed) 并让重复插入失败。但是,由于相反的性质,在 delta 文档多于一个的情况下,_id 不会被插入时排序。所以,每次查询都需要调用.sort({"timestamp":1})

此外,如果我想使用时间序列集合 (mongodb>=5.0),则不支持唯一索引。

# mongosh
db.stocks.createIndex({"metadata.InstrumentId":1,"timestamp":1},{"unique":true})
>>> MongoServerError: Unique indexes are not supported on collections clustered by _id

选项 2:更新插入

我重写了现有文档,并且可以添加更新日期。但是,时间序列集合不支持更新。 此外,我必须在 for 循环中调用更新,这应该会降低效率:

for datapoint in datapoints:
    db.stocks.update_one(
        {
            "timestamp": ISODate("2021-05-18T00:00:00.000Z"),
            "metadata": [{"instrumentId": 5578}, {"FX": "USD"}, {"lastUpdate": ISODate(now)}]
        },
        {"$set":{
                "price": 12.5
            }
        },
        {"upsert":True})

目前我最好的猜测是选项 1 与正常集合。

更好的想法?

【问题讨论】:

  • _id 是一个唯一的时间戳字段(请参阅 ObjectId.getTimestamp(),为什么不使用它?我假设您的 timestamp 字段设置为“现在”。
  • 对了,我忘了说timestamp 不是“现在”,价格可以与当前时间异步写入。
  • 选项 1 的改进可以是 my_collection.insert_many(to_insert, ordered=False)here
  • 根据您正在编写/更新的文档数量,bulkWrite() 可能值得一看。

标签: mongodb time-series pymongo


【解决方案1】:

我能想到的最佳答案是 my_collection.insert_many(to_insert, ordered=False) 或按照Paul 的建议直接调用BulkWrite(仍然是无序的upsert)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 2012-11-16
    • 1970-01-01
    • 2011-11-14
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多