问题描述
我存储了以下mongo文档
I have a below mongo document stored
{
"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"的子文档
from the above, I want to fetch the subdocuments which is having id "123"
即.
{
"Field3" : "ABC1",
"Field4" : [ { "id": "123"} ]
} ,
{
"Field3" : "ABC2",
"Field4" : [ { "id": "123"} ]
}
1. Java way
A. use Mongo find method to get the ABC document from Mongo DB
B. for Loop to Iterate the Field2 Json Array
C. Again for Loop to Iterate over Field4 Json Array
D. Inside the nested for loop I've if condition to Match id value to "123"
E. Store the Matching subdocument into List
2. Mongo Way
A. Use Aggregation query to get the desired output from DB.No Loops and conditions in the Java side.
B. Aggregation Query below stages
I) $Match - match the ABC document
II) $unwind - Field2
III) $unwind - Field4
IV) $match - Match the with id ( value is "123")
V) $group - group the document based on Field3 (based on "ABC1" or "ABC2")
VI) execute aggregation and return results
两人都工作良好,并返回了适当的结果.
问题是哪个更好,为什么?我在restful service的get方法中使用了聚合,那么并行执行聚合查询1000次或更多次会导致性能问题吗?
Both are working good and returning proper results.
Question is which one is the better to follow and why ? I used the aggregation in restful service get method, So executing aggregation queries 1000 or more times in parallel will cause any performance problems?
推荐答案
有了聚合,整个查询将在MongoDB服务器上作为单个进程执行-应用程序将从服务器获取结果游标.
With Aggregation, the whole query is executed as a single process on the MongoDB server - the application program will get the results cursor from the server.
使用Java程序,您还可以从数据库服务器获取光标,作为对应用程序中处理的输入.来自服务器的响应游标将是更大的数据集,并且将使用更多的网络带宽.然后在应用程序中进行处理,这增加了更多步骤来完成查询.
With Java program also you are getting a cursor from the database server as input to the processing in the application. The response cursor from the server is going to be larger set of data and will use more network bandwidth. And then there is processing in the application program, and this adds more steps to complete the query.
我认为聚合选项是一个更好的选择-因为所有处理(初始匹配和过滤数组)都在数据库服务器上作为单个进程进行.
I think the aggregation option is a better choice - as all the processing (the initial match and filtering the array) happens on the database server as a single process.
此外,请注意,您可以高效地完成已发布的聚合查询步骤.您可以分两个阶段完成这些操作,而不必分两个阶段(2、3、4和5)进行操作-将 $ project
与 $ map 在外部数组上,然后是
$ filter
在内部数组上,然后是 $ filter
在外部数组上.
Also, note the aggregation query steps you had posted can be done in an efficient way. Instead of multiple stages (2, 3, 4 and 5) you can do those operations in a two stages - use a
$project
with $map
on the outer array and then $filter
on the inner array and then $filter
the outer array.
聚合:
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 ] }
}
}
}
},
] )
这篇关于Mongo聚合与Java的循环和性能对比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!