mongodb - mongoDB非分片集合中的多线程最佳实践
问题描述
我有一个相对较大的 1TB 数据库,带有 3x 层嵌套数组,但没有分片,我发现运行 100 个并行线程比使用 forEach() 处理所有数据库以从最后一层提取一些字段(10h 而不是 80h)更快。所以我的问题是:我是否可以根据从默认文档 _id 中提取的日期将数据拆分为块,或者在多个并行线程而不是 1 中处理集合中所有数据的最佳实践是什么,是否有任何简单的选项可以拆分?一次将数据等分到所有线程?
(做 skip() / limit() 似乎很耗时且无效)
这是单个文档示例:
db.m.findOne()
{
"_id":ObjectId("56c5e1ca4537ddec8950ed20"),
"f":"xyz",
"apps":[
{
"aID":"mnk",
"aDate":"20210101",
"apId":"test1",
"proc":[
{
"procID":1,
"procDate":"202101",
"s":{
"c":{ "t":[ {"sid":1 } ,{"sid":2} , {"sid":4} ]},
"d":{ "t":[ {"sid":7} , {"sid":46} ]} ,
"a":{ "t":[ {"sid":12 } ,{"sid":22} , {"sid":54} ]} ,
}
},
{
"procID":2,
"procDate":"202102",
"s":{
"c":{ "t":[ {"sid":200 } ]},
"d":{ "t":[ {"sid":700} , {"sid":200} ]} ,
"a":{ "t":[ {"sid":1 } ,{"sid":220} ]} ,
}
}
]
}
]
}
这是我尝试根据“apps.proc.procDate”字段拆分查询并使其成为多线程:
cursor = collection.aggregate([
{"$unwind" : "$apps"},
{"$unwind" : "$apps.proc"},
{"$match" : {"apps.proc.procDate" : date}},
{"$limit" : LIMIT},
{"$project" : {
"F_ID" : "$f",
"A_ID" : "$apps.apId",
"P_ID" : "$apps.proc.procID",
"SRC_ID_SET" :
{"$setUnion" : [
"$apps.proc.s.c.t.sid","$apps.proc.s.d.t.sid","$apps.proc.s.a.t.sid"
]}
,
"_id" : 0
}}
])
但我觉得可以更好...
解决方案
不完全清楚你的最终意图是什么。
{"$unwind" : "$apps"},
{"$unwind" : "$apps.proc"},
{"$match" : {"apps.proc.procDate" : date}},
{"$limit" : LIMIT}
可以写成
{
$set: {
apps: {
$map: {
input: "$apps",
as: "app",
in: {
$mergeObjects: [
"$$app",
{
proc: {
$slice: [{
$filter: {
input: "$$app.proc",
cond: { $eq: ["$$this.procDate", date] }
}
}, LIMIT]
}
}
]
}
}
}
}
}
为了
{
"$project": {
"F_ID": "$f",
"A_ID": "$apps.apId",
"P_ID": "$apps.proc.procID",
"SRC_ID_SET": { "$setUnion": ["$apps.proc.s.c.t.sid", "$apps.proc.s.d.t.sid", "$apps.proc.s.a.t.sid"] },
"_id": 0
}
}
另一种方法是
{
$set: {
apps: {
$map: {
input: "$apps",
as: "app",
in: {
A_ID: "$$app.apId",
P_ID: "$$app.proc.procID",
SRC_ID_SET: {
$setUnion: {
$reduce: {
input: { $concatArrays: ["$$app.proc.s.c.t.sid", "$$app.proc.s.d.t.sid", "$$app.proc.s.a.t.sid"] },
initialValue: [],
in: { $concatArrays: ["$$value", "$$this"] }
}
}
}
}
}
}
}
}
你仍然需要经营一些化妆品,但我想你已经了解了它的基本概念。
推荐阅读
- java - gradle - 将源 jar 文件附加到依赖项
- c# - 从 Json 获取特定的子元素
- python - 如何使用 pyautogui 正确执行按下选项?
- reactjs - 在 useEffect() 中更新对象的状态是否会创建一个新对象?
- r - 从 R 中数据框中的观察结果生成新变量
- node.js - 在节点流期间捕获错误并继续处理流
- android - 覆盖视图函数android
- ajax - 在codeigniter中的jquery ajax json中带有空格的下拉名称值
- php - 用户名或电子邮件的 Wordpress 密码错误,使用“wp_insert_user”添加
- java - 反序列化同一文件中的许多对象(java)