1

线程“main”com.mongodb.MongoWriteException 中的异常:更新中未使用标识符“element”的数组过滤器 { $set: { leave_history: { leave_history.$[element].pl_used: 6, leave_history.$[element ].cl_used: 6, leave_history.$[element].sl_used: 6 } } } at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1060) at com.mongodb.client.internal.MongoCollectionImpl.executeUpdate (MongoCollectionImpl.java:1037) 在 com.mongodb.client.internal.MongoCollectionImpl.updateOne(MongoCollectionImpl.java:622) 在 MongoDBExample.displayempDocs(MongoDBExample.java:226) 在 MongoDBExample.main(MongoDBExample.java:253)

考虑文件

ali@MongoDB>db.employees.find({$and : [{empno:7839},{leave_history:{$exists:true}}]}).pretty()

{
        "_id" : ObjectId("5e907ad23997181dde06e8fc"),
        "empno" : 7839,
        "ename" : "KING",
        "mgrno" : 0,
        "hiredate" : "1990-05-09",
        "sal" : 100000,
        "deptno" : {
                "_id" : ObjectId("5e9065f53997181dde06e8f8")
        },
        "username" : "none",
        "password" : "none",
        "is_admin" : "N",
        "is_approver" : "Y",
        "is_manager" : "Y",
        "user_role" : "AP",
        "admin_approval_received" : "Y",
        "active" : "Y",
        "created_date" : "2020-04-10",
        "updated_date" : "2020-04-10",
        "application_usage_log" : [
                {
                        "logged_in_as" : "AP",
                        "log_in_date" : "2020-04-10"
                },
                {
                        "logged_in_as" : "EM",
                        "log_in_date" : ISODate("2020-04-16T07:28:11.959Z")
                }
        ],
        "leave_history" : [
                {
                        "calendar_year" : 2020,
                        "pl_used" : 1,
                        "cl_used" : 2,
                        "sl_used" : 0
                },
                {
                        "calendar_year" : 2021,
                        "pl_used" : 0,
                        "cl_used" : 0,
                        "sl_used" : 0
                }
        ]
}

我正在尝试更新字段 [leave_history],它是包含其他四个字段的子文档数组。具体来说,pl_used、cl_used 和 sl_used 字段需要更新。使用了以下代码段

//Update the leaves used for this employee.
        query = and(eq("empno",7839),exists("leave_history",true)); // parent document query 

        Bson update = new Document("$set",new Document("leave_history",new Document("leave_history.$[element].pl_used",6)
                .append("leave_history.$[element].cl_used", 6).append("leave_history.$[element].sl_used", 6)));


        UpdateOptions update_options = new UpdateOptions(); // setting the options for sub-document arrays.
        List<Bson> array_filters = new ArrayList<Bson>();   // array list of filters.
        Bson arrayElement = Filters.eq("element.calendar_year", year); //creating the array element 
        array_filters.add(arrayElement);                         // add the filter element to the list of array list filters. 
        update_options.arrayFilters(array_filters);              // add the filters to the updateOptions. 
        update_result = generic_collection.updateOne(query, update, update_options); // calling the update.

但这引发了上述异常。异常是什么意思?是否有另一种方法可以使用子文档数组更新多个字段?

您好,Joe,我有 Mongo Shell 所需的查询。这是我正在使用的

db.employees.updateOne({empno:7839},{$set: {"leave_history.$[elem].pl_used":6,"leave_history.$[elem].cl_used":6,"leave_history.$[elem].sl_used":6}},{arrayFilters:[{"elem.calendar_year":2020}]})

当我尝试在 Java 程序中复制它时遇到了问题。

4

1 回答 1

3

您最终运行的更新操作似乎是:

db.collection.update({"empno":7839), "leave_history",{$exists:true}},
                     {"$set":{ "leave_history":{
                                    "leave_history.$[element].pl_used":6,
                                    "leave_history.$[element].cl_used":6,
                                    "leave_history.$[element].sl_used":6
                     }}},
                     {"arrayFilters":[{"element.calendar_year":year}]}
)

问题是$set试图leave_history用包含对象的对象替换数组leave_history,因此永远不会进行数组元素比较。

您只需要删除一层文档,以便您的更新是:

db.collection.update({"empno":7839), "leave_history",{$exists:true}},
                     {"$set":{
                                    "leave_history.$[element].pl_used":6,
                                    "leave_history.$[element].cl_used":6,
                                    "leave_history.$[element].sl_used":6
                     }},
                     {"arrayFilters":[{"element.calendar_year":year}]}
)
于 2020-04-17T22:40:32.883 回答