Исключение в потоке "main" com.mongodb.MongoWriteException: фильтр массива для идентификатора элемента не использовался в обновлении - PullRequest
0 голосов
/ 17 апреля 2020

Исключение в потоке "main". Com.mongodb.MongoWriteException: Фильтр массива для идентификатора 'element' не использовался в обновлении {$ set: {exit_history: {exit_history. $ [Element] .pl_used: 6, exit_history. $ [element] .cl_used: 6, оставьте историю. внутреннее. .main (MongoDBExample. java: 253)

Рассмотрим документ

ali@MongoDB> db.employees.find ({$ and: [{empno: 7839}, {exit_history: {$ exist: 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
                }
        ]
}

Я пытаюсь обновить поле [left_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.

Но это вызывает исключение, указанное выше. Что означает исключение? Есть ли другой способ обновить несколько полей с помощью массива поддокументов?

Здравствуйте, Джо, у меня есть запрос, который необходим для оболочки Mon go. Вот что я использую

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 программе.

1 Ответ

1 голос
/ 18 апреля 2020

Операция обновления, которую вы в конечном итоге выполняете, выглядит следующим образом:

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}]}
)
...