Запрос Morphia к массиву вложенных документов с использованием elem

У меня есть следующая структура документа в коллекции mongodb «Контакт». Существует массив вложенных документов, называемых «числами»:

{
    "name" : "Bill",
    "numbers" : [
        {
            "type" : "home",
            "number" : "01234",
        },
        {
            "type" : "business",
            "number" : "99099"
        },
        {
            "type" : "fax",
            "number" : "77777"
        }
    ]
}

Когда я хочу запросить только «домашний» и «рабочий» номера, я могу сделать что-то вроде этого в mongodb-shell:

db.Contact.find({ numbers: { $elemMatch: { 
        type : { $in : ["home", "business"]}, 
        number: { $regex : "^012" }
}}});

Но как это сделать в морфии? Там в любом случае?

Я понимаю, что "$elemMatch" поддерживается в morphia. Итак, я мог бы сделать что-то вроде:

query.filter("numbers elem", ???);

Но как именно добавить комбинированный запрос для вложенного документа?


person Chris Tian    schedule 29.08.2013    source источник


Ответы (2)


Слишком поздно, но, возможно, другим это может пригодиться.

Я нашел это решение https://groups.google.com/forum/#!topic/morphia/FlEjBoSqkhg

query.filter("numbers elem", 
BasicDBObjectBuilder.start()
.push("type").add("$in", new String[]{"home", "business"}).pop()
.push("number").add("$regex", "^012").pop().get());
person Robertiano    schedule 23.04.2015

Вместо использования морфия рассмотрите возможность использования jongo. Он позволяет вам запрашивать MongoDB так же, как вы использовали оболочку MongoDB. Кроме того, это даст вам больше свободы при отображении элементов массива. Вот как будет выглядеть ваш пример с джонго:

contacts_collection.find("{numbers : {$elemMatch: {
                                         type: {$in :#},
                                         number: {$regex: #}  
                                                  }
                                     }
                          }", 
                         new String[]{"home", "business"}, "^012")
                   .as(Contact.class);

Обратите внимание, что если вам нужен только один числовой объект (или несколько) из массива, вы можете использовать собственный сопоставитель/обработчик результатов. Вам просто нужно заменить .as(Contact.class) на:

.map(new ResultHandler<Number>() {...})  

Полный пример см. в моем сообщении в блоге или в моем репозитории GitHub

person Ivan Hristov    schedule 13.10.2013