mongodb不使用索引的时间序列数据



我是MongoDB和NoSQL的新手,我正试图在一个巨大的数据集(大约5000万个文档)上运行查询

我在Windows 10主机上使用Docker运行最新版本的MongoDB,内存为64 GB。

我使用pymongo来导入数据并运行查询,我也有Mongo Express作为docker容器运行以查看导入的数据。

创建时间序列集合的语句是:

mydb.command('create', 'sensor_data', timeseries={
'timeField': 'collection_time', 
'metaField': 'sensor' 
})

每个文档看起来像这样:

{
"sensor": { "id": 1, "location":"Somewhere"},
"collection_time": datetime.strptime("2022/01/01 01:23:45 PM", '%Y/%m/%d %I:%M:%S %p'),
...
}

我已经能够使用Mongo Express来验证数据是否已正确加载到MongoDB。

然后我尝试运行以下代码:

res = mycol.find({
"collection_time": { 
"$gte": datetime.strptime("2021/01/01 12:00:00 AM", '%Y/%m/%d %I:%M:%S %p'), 
"$lte": datetime.strptime("2022/02/01 12:00:00 AM", '%Y/%m/%d %I:%M:%S %p') 
}
})

但是这个查询需要很长时间才能运行。

运行res.explain()后,我可以看到该操作正在执行COLSCAN而不使用索引。我甚至尝试手动创建一个索引上的'collection_time',但查询仍在做COLSCAN。我错过了什么?

<标题>

更新1多亏了R2D2的解决方案,我已经为find()工作了,但我不能让它为aggregate()工作下面是我的代码:

res = mycol.aggregate([
{ 
"$match": {
"collection_time": { 
"$gte": datetime.strptime("2021/01/01 12:00:00 AM", '%Y/%m/%d %I:%M:%S %p'), 
"$lte": datetime.strptime("2022/02/01 12:00:00 AM", '%Y/%m/%d %I:%M:%S %p') 
}
}
},
{"$group":
{ 
"_id": {
"year" : { "$year" : "$collection_time" },        
"month" : { "$month" : "$collection_time" },        
"day" : { "$dayOfMonth" : "$collection_time" },
}, 
"count":{ "$sum": 1}
}
}
], {hint: "collection_time_1" })
NameError: name 'hint' is not defined

hint放在引号中会产生错误:AttributeError: 'dict' object has no attribute '_txn_read_preference'

默认情况下,当您创建时间序列集合时,它对于存储时间序列数据是有效的,但是没有创建索引,您可以为时间序列集合创建二级索引以提高查询的性能,如果查询规划器没有选择某些已创建的索引,您可以使用索引名称向查询添加hint()(您可以使用db.collection.getIndexes()获得索引名称)

对于mongodb 3.6+,您也可以在聚合框架中使用提示,如下所示:

db.collection.aggregate(pipeline, {hint: "index_name"})

最新更新