我在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中我目前正在做什么?
答案 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
}
}
]
另外,认为无需在任何地方使用$
符号。