Запросить документ по элементам массива в MongoDB с использованием Java

Я новичок в MongoDB. Мой образец документа

{
    "Notification" : [
        {
            "date_from" : ISODate("2013-07-08T18:30:00Z"),
            "date_too" : ISODate("2013-07-30T18:30:00Z"),
            "description" : "fdfd",
            "url" : "www.adf.com"
        },
        {
            "date_from" : ISODate("2013-07-01T18:30:00Z"),
            "date_too" : ISODate("2013-07-30T18:30:00Z"),
            "description" : "ddddddddddd",
            "url" : "www.pqr.com"
        }
    ],

Я пытаюсь обновить уведомление, "url" : "www.adf.com". Мой код Java для этого:

BasicDBObject query=new BasicDBObject("url","www.adf.com");

DBCursor f = con.coll.find(query);

Он не ищет документ, чей "url" есть "www.adf.com".

Ответ 1

В этом случае у вас есть вложенный документ. В вашем документе есть поле Notification, которое представляет собой массив, хранящий несколько под-объектов с полем url. Чтобы выполнить поиск в подполе, вам необходимо использовать точечный синтаксис:

BasicDBObject query=new BasicDBObject("Notification.url","www.adf.com");

Это, однако, вернет весь документ со всем массивом Notification. Вероятно, вам нужен только суб-документ. Чтобы отфильтровать это, вам нужно использовать двухпараметрическую версию Collection.find.

BasicDBObject query=new BasicDBObject("Notification.url","www.example.com");
BasicDBObject fields=new BasicDBObject("Notification.$", 1);

DBCursor f = con.coll.find(query, fields);

.$ означает "только первая запись этого массива, которая соответствует оператору find"

Это должно по-прежнему возвращать один документ с под-массивом Notifications, но этот массив должен содержать только запись, в которой url == "www.example.com".

Чтобы пройти этот документ с помощью Java, выполните следующие действия:

BasicDBList notifications = (BasicDBList) f.next().get("Notification"); 
BasicDBObject notification = (BasicDBObject) notifications.get(0);
String url = notification.get("url");

Кстати: Когда ваша база данных растет, вы, вероятно, столкнетесь с проблемами производительности, если только вы не создаете индекс, чтобы ускорить этот запрос:

con.coll.ensureIndex(new BasicDBObject("Notification.url", 1));

Ответ 2

Что делать, если я хочу посмотреть только последний элемент массива (уведомление)? Можете привести пример?