我有一个名为“实例”的集合,我必须将其存档。所谓归档,我的意思是某个月的每个文档都必须进入一个名为instance_XYZmonth的归档表中。例如,从2022年3月开始的文档应该进入到“instance2022-03”中。
我的问题是,这个“实例”集合很大,里面有2.26亿个文档,简单地计算文档需要6-7分钟。
为了解决这个问题,设计此表的人为_id创建了自己的格式,如下所示:
f96e67f3-2bc4-4c2c-9752-d7f0be657fd1_2017-10-31:15
因此,当我想找到与某个日期相关的文档时,我必须运行以下正则表达式:
db.getCollection("instance").find({
_id: {
$regex: '.*_2022-03-(?:0[1-9]|[1-2]\\d|30).*'
}
}).count()这个查询是在python脚本中运行的,它必须运行该查询几次(因为我使用的是极限500 000,所以它必须运行几次,直到没有剩下的行,但是每个循环只需6-7分钟就可以计数文档!)。
while total_documents > 0:
logger.info(f'{total_documents} documents to cleanup')
try:
destination_collection.insert_many(data_to_cleanup, ordered=False)
query = {"_id": {"$regex": regex_value}}
source_collection.delete_many(query)
except:
print("Error")
data_to_cleanup = source_collection.find({
'_id': {
'$regex': regex_value
}
}, limit=500000)
total_documents = data_to_cleanup.count()我该怎么做才能让我的生活更轻松?
发布于 2022-03-18 16:29:37
正则表达式总是昂贵而缓慢的。如果可能的话,您应该更改数据模型。
也许使用$split
db.getCollection("instance").aggregate([
{ $set: { timestamp: { $last: { $split: ["$_id", "_"] } } } },
{ $set: { timestamp: { $first: { $split: ["$timestamp", ":"] } } } },
{ $set: { timestamp: { $toDate: "$timestamp" } } }
{ $match: { timestamp: ... } }
])或者是一行:
{ $set: { timestamp: { $toDate: { $first: { $split: [{ $last: { $split: ["$_id", "_"] } }, ":"] } } } } }如果“清理”意味着“删除”,那么可能是这个:
db.getCollection("instance").updateMany(
{},
[
{ $set: { timestamp: { $last: { $split: ["$_id", "_"] } } } },
{ $set: { timestamp: { $first: { $split: ["$timestamp", ":"] } } } },
{ $set: { timestamp: { $toDate: "$timestamp" } } }
]
)
db.getCollection("instance").deleteMany({timestamp: ...})https://stackoverflow.com/questions/71528653
复制相似问题