Mongo聚合与Java的循环和性能



我存储了一个下面的 mongo 文档

{
"Field1": "ABC",
"Field2": [
{ "Field3": "ABC1","Field4": [ {"id": "123" }, { "id" : "234" }, { "id":"345" }] }, 
{ "Field3": "ABC2","Field4": [ {"id": "123" }, { "id" : "234" }, { "id":"345" }] }, 
{ "Field3": "ABC3","Field4": [{ "id":"345" }] },  
]
}

从上面,我想获取 ID 为"123"的子文档

即。

{ 
"Field3" : "ABC1",
"Field4" : [ { "id": "123"} ]
} ,
{
"Field3" : "ABC2",
"Field4" : [ { "id": "123"} ]
}
1. 爪哇方式  A. 使用Mongo查找方法从Mongo DB获取ABC文档 b. for 循环迭代 field2 json 数组 C.再次让循环遍历 Field4 json 数组 D. 在嵌套的 for 循环中,我有 if 条件将 id 值匹配到"123" E. 将匹配的子文档存储到列表中 2. 蒙戈之路  A. 使用聚合查询从 Java 端的 DB.No 循环和条件获取所需的输出。  B. 以下阶段的聚合查询 I( $Match - 匹配ABC文档 II( $unwind - 字段 2 III( $unwind - 字段4 IV( $match - 与 id 匹配(值为"123"( V( $group - 根据字段 3(基于"ABC1"或"ABC2"(对文档进行分组 VI( 执行聚合

并返回结果两者都运行良好并返回适当的结果。
问题是哪一个更好遵循,为什么?我在 restful service get 方法中使用了聚合,所以并行执行 1000 次或更多次聚合查询会导致任何性能问题吗?

使用聚合,整个查询在MongoDB服务器上作为单个进程执行 - 应用程序将从服务器获取结果光标。

使用 Java 程序,您还可以从数据库服务器获取游标作为应用程序中处理的输入。来自服务器的响应光标将是更大的数据集,并将使用更多的网络带宽。然后是应用程序中的处理,这增加了更多步骤来完成查询。

我认为聚合选项是更好的选择 - 因为所有处理(初始匹配和过滤数组(都作为单个进程在数据库服务器上发生。

另请注意,已发布的聚合查询步骤可以通过有效的方式完成。您可以分两个阶段执行这些操作,而不是多个阶段(2、3、4 和 5( - 在外部数组上使用带有$map$project,然后在内部数组上使用$filter然后$filter外部数组。

聚合:

db.test.aggregate( [
{ 
$addFields: { 
Field2: { 
$map: {
input: "$Field2",
as: "fld2",
in: {
Field3: "$$fld2.Field3",
Field4: { 
$filter: {
input: "$$fld2.Field4",
as: "fld4",
cond: {  $eq: [ "$$fld4.id", "123" ] }
}
}
}
} 
}
}
},
{ 
$addFields: { 
Field2: { 
$filter: {
input: "$Field2",
as: "f2",
cond: {  $gt: [ { $size: "$$f2.Field4" }, 0 ] }
}
}
}
},
] )

第二种方法可能更好,因为它从数据存储返回较小的结果;通过线路传输位的成本很高。

最新更新