У меня есть строка 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, но по какой-то причине он не работает, я, вероятно, что-то делаю не так. Может кто-нибудь указать на проблему, пожалуйста?
Кроме того, как лучше всего вести подсчет документов в массиве, чтобы после извлечения всех документов весь документ был удален из базы данных? Было бы хорошо добавить какой-нибудь атрибут «размер», отслеживать размер и уменьшать его после каждого вытягивания?




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.
Чтобы удалить документ с Order=54321 из внутреннего массива любого документа (если вы не знаете ID), вы можете использовать пустой фильтр, например:
Document filter = new Document();
Document update = new Document("$pull", new Document("ObjData", new Document("Order", "54321")));
coll.updateOne(filter, update);