使用 spring 引导 mongotemplate 更新第二级嵌套数组元素的问题
Issue with update 2nd level nested array element using spring boot mongotemplate
问题文件
{
"_id": ObjetId("5b91ce1d001902722e79539b")
...
"questionDetail": {
...
"answers": [
{
"srno": 10,
...
"userMatchPairAnswerCounts": [
{
"anssrno": 8,
"anscnt": 0
},
{
"anssrno": 9,
"anscnt": 0
}
]
},
{
"srno": 20,
...
"userMatchPairAnswerCounts": [
{
"anssrno": 14,
"anscnt": 0
},
{
"anssrno": 15,
"anscnt": 0
},
{
"anssrno": 16,
"anscnt": 0
}
]
}
...
}
Java 类
public class Question {
private QuestionDetail questionDetail;
...
}
public class QuestionDetail {
private List<Answer> answers = new ArrayList<>();
...
}
public class Answer {
private int srno;
private List<UserMatchPairAnswerCount> userMatchPairAnswerCounts;
...
}
public class UserMatchPairAnswerCount {
private int anssrno;
private long anscnt;
...
}
我的代码:
Query query = new Query( new Criteria().andOperator(Criteria.where("id").is(question.getId()),
Criteria.where("questionDetail.answers").elemMatch(Criteria.where("srno").is(10))));
Update update = new Update().inc("questionDetail.answers.$[answer].userMatchPairAnswerCounts.$.anscnt", 1)
.filterArray(new Criteria().andOperator(
Criteria.where("answer.srno").is(10),
Criteria.where("answer.userMatchPairAnswerCounts").elemMatch(Criteria.where("anssrno").is(9))));
Question questionFound = mongoTemplate.findAndModify(query, update, Question.class);
上面修改了“anssrno”:8(index 1 - 与所选 'answer' index 相同)
Query query = new Query( new Criteria().andOperator(Criteria.where("id").is(question.getId()),
Criteria.where("questionDetail.answers").elemMatch(Criteria.where("srno").is(20))));
Update update = new Update().inc("questionDetail.answers.$[answer].userMatchPairAnswerCounts.$.anscnt", 1)
.filterArray(new Criteria().andOperator(
Criteria.where("answer.srno").is(20),
Criteria.where("answer.userMatchPairAnswerCounts").elemMatch(Criteria.where("anssrno").is(16))));
Question questionFound = mongoTemplate.findAndModify(query, update, Question.class);
上面修改了“anssrno”:15(index 2 - 与所选 'answer' index 相同)
看起来像 filterArray 条件
"answer.userMatchPairAnswerCounts").elemMatch(Criteria.where("anssrno").is(16))));
没有任何影响,而是始终根据所选答案的索引 updates/inserts(如果所需索引处没有文档)。
我做错了什么?请指导
更新:
直接命令行工作正常:
db.questions.update({
"_id": ObjectId("5b91ce1d001902722e79539b"),
"questionDetail.answers.srno": 10
},
{
"$inc": {
"questionDetail.answers.$[answer].userMatchPairAnswerCounts.$[userMtc].anscnt": 1
}
},
{
arrayFilters: [
{
"answer.srno": 10
},
{
"userMtc.anssrno": 9
}
]
})
我的Spring开机Version:2.4.0MongoDB版本:4.2.3
按照下面的建议在我的 java 代码中添加了更改。低于错误
Caused by: com.mongodb.MongoCommandException: Command failed with error 9 (FailedToParse): 'Error parsing array filter :: caused by :: Expected a single top-level field name, found 'answer' and 'userMtc'' on server localhost:27017. The full response is {"ok": 0.0, "errmsg": "Error parsing array filter :: caused by :: Expected a single top-level field name, found 'answer' and 'userMtc'", "code": 9, "codeName": "FailedToParse"}
添加屏幕截图(调试)- 以防有帮助
您更新嵌套数组的用法不正确。也重构了代码。
Query query = new Query(Criteria.where("id").is(question.getId()).and("questionDetail.answers.srno").is(10));
Update update = new Update().inc("questionDetail.answers.$[answer].userMatchPairAnswerCounts.$[userMtc].anscnt", 1)
.filterArray(Criteria.where("answer.srno").is(10))
.filterArray(Criteria.where("userMtc.anssrno").is(9));
Question questionFound = mongoTemplate.findAndModify(query, update, Question.class);
问题文件
{
"_id": ObjetId("5b91ce1d001902722e79539b")
...
"questionDetail": {
...
"answers": [
{
"srno": 10,
...
"userMatchPairAnswerCounts": [
{
"anssrno": 8,
"anscnt": 0
},
{
"anssrno": 9,
"anscnt": 0
}
]
},
{
"srno": 20,
...
"userMatchPairAnswerCounts": [
{
"anssrno": 14,
"anscnt": 0
},
{
"anssrno": 15,
"anscnt": 0
},
{
"anssrno": 16,
"anscnt": 0
}
]
}
...
}
Java 类
public class Question {
private QuestionDetail questionDetail;
...
}
public class QuestionDetail {
private List<Answer> answers = new ArrayList<>();
...
}
public class Answer {
private int srno;
private List<UserMatchPairAnswerCount> userMatchPairAnswerCounts;
...
}
public class UserMatchPairAnswerCount {
private int anssrno;
private long anscnt;
...
}
我的代码:
Query query = new Query( new Criteria().andOperator(Criteria.where("id").is(question.getId()),
Criteria.where("questionDetail.answers").elemMatch(Criteria.where("srno").is(10))));
Update update = new Update().inc("questionDetail.answers.$[answer].userMatchPairAnswerCounts.$.anscnt", 1)
.filterArray(new Criteria().andOperator(
Criteria.where("answer.srno").is(10),
Criteria.where("answer.userMatchPairAnswerCounts").elemMatch(Criteria.where("anssrno").is(9))));
Question questionFound = mongoTemplate.findAndModify(query, update, Question.class);
上面修改了“anssrno”:8(index 1 - 与所选 'answer' index 相同)
Query query = new Query( new Criteria().andOperator(Criteria.where("id").is(question.getId()),
Criteria.where("questionDetail.answers").elemMatch(Criteria.where("srno").is(20))));
Update update = new Update().inc("questionDetail.answers.$[answer].userMatchPairAnswerCounts.$.anscnt", 1)
.filterArray(new Criteria().andOperator(
Criteria.where("answer.srno").is(20),
Criteria.where("answer.userMatchPairAnswerCounts").elemMatch(Criteria.where("anssrno").is(16))));
Question questionFound = mongoTemplate.findAndModify(query, update, Question.class);
上面修改了“anssrno”:15(index 2 - 与所选 'answer' index 相同)
看起来像 filterArray 条件
"answer.userMatchPairAnswerCounts").elemMatch(Criteria.where("anssrno").is(16))));
没有任何影响,而是始终根据所选答案的索引 updates/inserts(如果所需索引处没有文档)。
我做错了什么?请指导
更新:
直接命令行工作正常:
db.questions.update({
"_id": ObjectId("5b91ce1d001902722e79539b"),
"questionDetail.answers.srno": 10
},
{
"$inc": {
"questionDetail.answers.$[answer].userMatchPairAnswerCounts.$[userMtc].anscnt": 1
}
},
{
arrayFilters: [
{
"answer.srno": 10
},
{
"userMtc.anssrno": 9
}
]
})
我的Spring开机Version:2.4.0MongoDB版本:4.2.3 按照下面的建议在我的 java 代码中添加了更改。低于错误
Caused by: com.mongodb.MongoCommandException: Command failed with error 9 (FailedToParse): 'Error parsing array filter :: caused by :: Expected a single top-level field name, found 'answer' and 'userMtc'' on server localhost:27017. The full response is {"ok": 0.0, "errmsg": "Error parsing array filter :: caused by :: Expected a single top-level field name, found 'answer' and 'userMtc'", "code": 9, "codeName": "FailedToParse"}
添加屏幕截图(调试)- 以防有帮助
您更新嵌套数组的用法不正确。也重构了代码。
Query query = new Query(Criteria.where("id").is(question.getId()).and("questionDetail.answers.srno").is(10));
Update update = new Update().inc("questionDetail.answers.$[answer].userMatchPairAnswerCounts.$[userMtc].anscnt", 1)
.filterArray(Criteria.where("answer.srno").is(10))
.filterArray(Criteria.where("userMtc.anssrno").is(9));
Question questionFound = mongoTemplate.findAndModify(query, update, Question.class);