Удалить документ из массива в MongoDB Java

У меня есть строка JSON, которая выглядит примерно так:

String tmp = "[
   {
      "ID":"12",
      "Date":"2018-02-02",
      "ObjData":[
         {
            "Name":"AAA",
            "Order":"12345",
            "Extra1":{
               "Temp":"3"
            },
            "Extra2":{
               "Temp":"5"
            }
         },
         {
            "Name":"BBB",
            "Order":"54321",
            "Extra1":{
               "Temp":"3"
            },
            "Extra2":{
               "Temp":"5"
            }
         }
      ]
   }
]"

Я хотел бы, например, удалить документ, в котором «Заказ» равен «54321», из «ObjData». Получился такой код:

Document doc = new Document();
doc = Document.parse(tmp);

Document fields = new Document("ID", "12")
    .append("ObjData", Arrays.asList(new Document("Order", "54321")));

Document update = new Document("$pull", fields);

coll.updateOne(doc, update);

Я пытаюсь использовать метод «вытягивания», чтобы удалить весь документ из массива, где «Порядок» равен 54321, но по какой-то причине он не работает, я, вероятно, что-то делаю не так. Может кто-нибудь указать на проблему, пожалуйста?

Кроме того, как лучше всего вести подсчет документов в массиве, чтобы после извлечения всех документов весь документ был удален из базы данных? Было бы хорошо добавить какой-нибудь атрибут «размер», отслеживать размер и уменьшать его после каждого вытягивания?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
0
1 575
2

Ответы 2

Обновление записей для удаления значений из массива ObjData

Первый параметр метода updateOne - это запрос на поиск документа, который вы хотите обновить, а не всего документа.

Итак, для вашего кода, предполагая, что ID является уникальным значением и что в вашей коллекции есть элемент с ID из "12":

// { ID: "12" }
Document query = new Document("ID", "12");

// { ObjData: { $pull: { Order: "54321" } } }
Document update = new Document("ObjData",
        new Document("$pull",
                new Document("Order", "54321")
        )
);

coll.updateOne(query, update);

В качестве альтернативы, если вы хотите удалить заказ из всех документов в базе данных, просто замените query пустым Document, то есть:

// { <empty> }
Document query = new Document();

Удаление записей с пустым массивом ObjData

Что касается удаления записей, когда размер достигает нуля, вы можете использовать фильтр с $size:

db.myColl.deleteMany({ ObjData: { $size: 0 } })

Это также можно сделать с помощью драйвера Java:

// { ObjData: { $size: 0 } }
Document query = new Document("ObjData",
        new Document("$size", 0)
);
coll.deleteMany(query);

Обратите внимание, что для больших коллекций (т.е. там, где большой myColl, а не массив ObjData), это может работать не очень хорошо. В этом случае вы можете отслеживать размер отдельно (как вы намекали в своем вопросе) и индексировать его, чтобы ускорить поиск, поскольку вы не можете создать индекс для размера массива в MongoDB.

Рекомендации

  • updateOne документация для обновления документов с помощью драйвера Java
  • deleteOne документация для удаления документов с помощью драйвера Java
  • $pull документация для удаления документов из массива
  • $size документация для фильтрации документов по размеру массива

Чтобы удалить документ с Order=54321 из внутреннего массива любого документа (если вы не знаете ID), вы можете использовать пустой фильтр, например:

    Document filter = new Document();
    Document update = new Document("$pull", new Document("ObjData", new Document("Order", "54321")));

    coll.updateOne(filter, update);

Другие вопросы по теме