2014-12-22 2 views
0

Как создать запрос MongoDB с использованием BasicDBObjects в Java, когда я хочу найти все документы, содержащие массив вложенных документов, где один из этих вложенных документов соответствует всем указанным критериям ?Комплекс MongoDB находит запросы на больших документах в Java

Принимая пример данных:

[ 
    { 
     "_id":"blood_0", 
     "type":"O", 
     "list":[ 
     { 
      "firstname":"John", 
      "lastname":"Smith", 
      "zipcode":"12345" 
     }, 
     { 
      "firstname":"John", 
      "lastname":"Hamilton", 
      "zipcode":"54627" 
     }, 
     { 
      "firstname":"Ben", 
      "lastname":"Brick", 
      "zipcode":"12345" 
     }, 
     { 
      "firstname":"William", 
      "lastname":"Tell", 
      "zipcode":"15487" 
     } 
     ] 
    }, 
    { 
     "_id":"blood_1", 
     "type":"AB", 
     "list":[ 
     { 
      "firstname":"Mary", 
      "lastname":"Smith", 
      "zipcode":"12345" 
     }, 
     { 
      "firstname":"John", 
      "lastname":"Henry", 
      "zipcode":"54624" 
     }, 
     { 
      "firstname":"Jacob", 
      "lastname":"Tell", 
      "zipcode":"19283" 
     }, 
     { 
      "firstname":"William", 
      "lastname":"Dirk", 
      "zipcode":"15999" 
     } 
     ] 
    } 
] 

Если я только хочу, чтобы вернуть все объекты, которые содержат контакт в списке, который соответствует критериям Firstname = William, Lastname = Расскажите как бы я продолжайте это делать? Запросы, которые я выполняю, не группируют критерии, поэтому я получаю два результата, в которых я должен только получать их.

Как бы я сделал тот же запрос, но также проверил на тип = AB, а также другие критерии, которые не дали бы никаких результатов?

+0

http://docs.mongodb.org/manual/reference/method/db.collection.find/#query-an-array-of-documents –

+0

Я знаю, как должен работать запрос, если я собираюсь запрос MongoDB, я не знаю, как воссоздать его в Java с помощью BasicDBObject. – Joe

ответ

2

Вы ищете оператор $elemMatch. Он ограничивает операторы запроса одним элементом в массиве значений.

В оболочке ваш запрос будет выглядеть следующим образом:

db.people.find({ list : { $elemMatch : { lastName:"Smith", firstName: "John" } } }) 

Чтобы добавить тип крови:

db.people.find({ 
     type : "AB", 
     list : { $elemMatch : { lastName:"Smith", firstName: "John" } } 
}) 

Это становится немного многословным с помощью драйвера Java.

DBObject elemMatch = new BasicDBObject(); 
elemMatch.put("lastName","Smith"); 
elemMatch.put("firstName","John"); 

DBObject query = new BasicDBObject(); 
query.append("type", "AB"); 
query.append("list", elemMatch); 

Передайте этот запрос одному из методов find() в коллекции, и вы должны получить документы, которые ищете.

Обратите внимание, что оператор запроса $ elemMatch вернет весь документ, включая все элементы в массиве. Существует аналогичный оператор проекции, чтобы ограничить элементы массива, возвращенные только согласованным.

HTH - Rob.

+0

Спасибо, это то, что я искал. – Joe

0

Прежде всего. Я действительно думаю, что ваша модель совершенно неверна. Вложенные массивы, которые потенциально растут indefinetly плохо по нескольким причинам:

  1. Если документ превышает это padding, когда новые члены записываются в массив, документ должен быть перенесены в файл данных. Это довольно дорогостоящая операция, и вы хотите предотвратить ее как можно больше.
  2. Документы BSON ограничены 16 МБ. Таким образом, по типу крови у вас может быть только ограниченное количество людей.
  3. Все запросы, как правило, немного сложнее, соответствующий код более раздутый и, следовательно, медленнее.

Итак, как это сделать? Возьмите эти документы:

{ 
    _id: ObjectId(), 
    firstName: "Mary", 
    lastName: "Smith", 
    zip: "12345", 
    bt: "AB" 
}, 
{ 
    _id: ObjectId(), 
    firstName: "John", 
    lastName: "Smith", 
    zip: "12345", 
    bt: "0" 
} 

индексах установлен как

db.people.ensureIndex({lastName:1,firstName:1}) 
db.people.ensureIndex({bt:1}) 

на MongoDB оболочки, вы можете получить то, что вы хотите с

db.people.find({ lastName:"Smith", firstName: "John"}) 

или

db.people.find({ bt: "AB" }) 

Этом запрос, например, переводит на ng

MongoClient client = new MongoClient("localhost"); 

DB db = client.getDB("yourDB"); 
DBCollection coll = db.getCollection("yourCollection"); 

BasicDBOBject query = new BasicDBObject("bt","AB"); 
DBCursor cursor = coll.find(query); 

try { 

    while(cursor.hasNext()) { 

    System.out.println(cursor.next()); 

    } 

} finally { 

    cursor.close(); 

} 

Возможно, вы найдете MongoDB introduction for working with a Java driver.

+0

Эти данные являются просто примером для визуализации того, что я просил, поскольку мне не разрешено публиковать модель данных, с которой я работаю, массивы не являются неопределенными. Я не создал модель данных, и у меня нет времени или разрешения на внесение в нее изменений. Я просто спрашиваю, как написать запрос с помощью драйверов Java Mongo, чтобы успешно получить правильные результаты, которые я ищу. – Joe

+0

Ну, я привел пример и ссылку на документы. В качестве примечания я хотел бы добавить, что модель является _everything_ в MongoDB. Поэтому я хотел бы указать вам на [документы моделирования] (http://docs.mongodb.org/manual/core/data-modeling-introduction/). –

+0

В этом примере показан основной запрос на поиск, и вы реорганизовали мои данные ... Мой вопрос связан с поиском документов на основе поиска вложенных массивов объектов по критериям. Если вам нужно лучше понять, что такое мои данные, представьте коллекцию профилей клиентов, каждый документ имеет массив объектов метода контакта. Я хочу выполнить поиск по этим объектам контактного метода с использованием нескольких критериев. – Joe