Spring MongoDB聚合组-无法正确获取组查询

时间:2019-05-28 06:26:04

标签: java spring mongodb group-by aggregate

我在MongoDB中有一个文档,如下所示。

from tkinter import*

currentsum=0

def addition():
   global currentsum # New
   currentsum+=float(e1.get()) # Fix
   #e1.insert(INSERT,str(currentsum))
   l2['text'] = str(currentsum) # Change

def subtraction():
   global currentsum # New
   currentsum=currentsum-float(e1.get())
   #e1.insert(INSERT,str(currentsum))
   l2['text'] = str(currentsum) # Change

def reset():
   global currentsum # New
   currentsum=0
   #e1.insert(INSERT,str(currentsum))
   l2['text'] = str(currentsum) # Change
window=Tk()

l1=Label(window,text="current sum:")
l1.grid(row=0, column=0)
l2=Label(window,text=str(currentsum))
l2.grid(row=0,column=1)

e1=Entry(window)
e1.grid(row=1,column=0)


b1=Button(window,text="ADD(+)",command=addition)
b2=Button(window,text="SUBTRACT(-)",command=subtraction)
b3=Button(window,text="RESET",command=reset)
b1.grid(row=2,column=0)
b2.grid(row=2,column=1)
b3.grid(row=2,column=2)

window.mainloop()

我对获得如下结果感兴趣。

{
    "_id" : ObjectId("5ceb812b3ec6d22cb94c82ca"),
    "key" : "KEYCODE001",
    "values" : [ 
        {
            "classId" : "CLASS_01",
            "objects" : [ 
                {
                    "code" : "DD0001"
                }, 
                {
                    "code" : "DD0010"
                }
            ]
        }, 
        {
            "classId" : "CLASS_02",
            "objects" : [ 
                {
                    "code" : "AD0001"
                }
            ]
        }
    ]
}

为此,我在Robo 3T中提出了一个聚合管道,如下所示。而且它按预期工作。

{
    "classId" : "CLASS_01",
    "objects" : [ 
        {
            "code" : "DD0001"
        }, 
        {
            "code" : "DD0010"
        }
    ]
}

现在,当我尝试在SpringBoot应用程序中执行相同操作时,我无法使其运行。我最终遇到错误[ { $match:{ 'key':'KEYCODE001' } }, { "$unwind":{ "path": "$values", "preserveNullAndEmptyArrays": true } }, { "$unwind":{ "path": "$values.objects", "preserveNullAndEmptyArrays": true } }, { $match:{ 'values.classId':'CLASS_01' } }, { $project:{ 'object':'$values.objects', 'classId':'$values.classId' } }, { $group:{ '_id':'$classId', 'objects':{ $push:'$object' } } }, { $project:{ '_id':0, 'classId':'$_id', 'objects':'$$objects' } } ] 。以下是我到目前为止在Java中所做的事情。

java.lang.IllegalArgumentException: Invalid reference '$complication'!

我在做什么错?经过研究,我发现组中的多个字段不起作用或类似的问题(请参考this question)。那么,在Spring Boot中我目前正在做什么?

1 个答案:

答案 0 :(得分:0)

经过数小时的调试和反复试验,发现以下解决方案有效。

final Aggregation aggregation = newAggregation(
        match(Criteria.where("key").is("KEYCODE001")),
        unwind("values", true),
        unwind("values.objects", true),
        match(Criteria.where("values.classId").is("CLASS_01")),
        project().and("values.classId").as("classId").and("values.objects").as("object"),
        group(Fields.from(Fields.field("_id", "classId"))).push("object").as("objects"),
        project().and("_id").as("classId").and("objects").as("objects")
);

这全部归结为group(Fields.from(Fields.field("_id", "classId"))).push("object").as("objects"),它引入了一个org.springframework.data.mongodb.core.aggregation.Fields对象,该对象包装了org.springframework.data.mongodb.core.aggregation.Field对象的列表。在Field中,可以封装字段名称和目标名称。这导致以下管道与预期匹配。

[
    {
        "$match" :{
            "key" : "KEYCODE001"
        }
    }, 
    {
        "$unwind" :{
            "path" : "$values", "preserveNullAndEmptyArrays" : true
        }
    }, 
    {
        "$unwind" :{
            "path" : "$values.objects", "preserveNullAndEmptyArrays" : true
        }
    }, 
    {
        "$match" :{
            "values.classId" : "CLASS_01"
        }
    }, 
    {
        "$project" :{
            "classId" : "$values.classId", "object" : "$values.objects"
        }
    }, 
    {
        "$group" :{
            "_id" : "$classId",
            "objects" :{
                "$push" : "$object"
            }
        }
    }, 
    {
        "$project" :{
            "classId" : "$_id", "objects" : 1
        }
    }
]

另外,认为无需在任何地方使用$符号。