我是 MongoDB 和 NoSQL 的新手,我正在嘗試對一個龐大的資料集(大約 5000 萬個檔案)運行查詢
我正在使用 Docker 在具有 64 GB RAM 的 Windows 10 主機上運行最新版本的 MongoDB。
我正在使用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(),我可以看到該操作正在執行 aCOLSCAN而不是使用索引。我什至嘗試在“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'
uj5u.com熱心網友回復:
默認情況下,當你創建時間序列集合時,它對存盤時間序列資料是有效的,但是沒有創建索引,你可以為時間序列集合創建二級索引以提高查詢性能,如果查詢計劃器不選擇某些創建的索引您可以使用索引名稱將 hint() 添加到查詢中(您可以使用 db.collection.getIndexes() 獲取索引名稱)
對于 mongodb 3.6 ,您也可以在聚合框架中使用提示,如下所示:
db.collection.aggregate(pipeline, {hint: "index_name"})
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/495738.html
