У меня есть два сборника и авторов . Почтовый документ содержит, помимо данных сообщения, идентификатор ссылки DBref для автора _id . Моя коллекция выглядит так:
сообщений
"_id" : ObjectId("4fa12443d3269e98070013b4"), "author" : { "$ref" : "authors", "$id" : ObjectId("4fa1242bd3269e9807000023") }, "post" : " mi eleifend egestas. Sed pharetra, felis eget varius ultrices, mauris ipsum porta elit, a feugiat tellus lorem eu metus. In lorem.", "post_title" : "Volutpat. Nulla facilisis. Suspendisse commodo tincidunt nibh. Phasellus nulla. Integer", "date" : 1293803276, "rating" : 8, "comments" : [{ "name" : "Doris Turner", "email" : "Hedda_Herman@.com", "upVotes" : 81, "downVotes" : 93, "comment_date" : 1111395830, "comment" : "consectetuer ipsum nunc id enim. Curabitur massa. Vestibulum accumsan neque et nunc. Quisque ornare tortor at" }, { "name" : "Brenda Tyler", "upVotes" : 1, "downVotes" : 73, "comment_date" : 940325674, "comment" : "cursus purus. Nullam scelerisque neque sed sem egestas blandit. Nam Nulla aliquet. Proin velit. Sed malesuada augue ut lacus. Nulla tincidunt, neque vitae semper egestas, urna justo faucibus lectus, a sollicitudin orci sem eget massa."}], "tags" : ["tag1", "tag3"] }
И моя коллекция авторов выглядит так:
авторы
{ "_id" : ObjectId("4fa1242bd3269e9807000016"), "name" : "Kristina Chung ", "email" : "curran_ramos@google.co.id\r\n.dk", "age" : 60, "city" : "Copenhagen" }
Я пытаюсь создать «реляционный» запрос, чтобы найти: сообщения с рейтингом больше 6 и менее 9, а возраст автора сообщения больше 19 и менее 25.
Я пытаюсь объединить это, но, похоже, не может получить правильные данные.
Первый запрос находится в моей коллекции сообщений и выглядит так:
$query = array('rating' => array('$gte' => 6, '$lt' => 9), 'comments.upVotes' => array('$gt' => 2, '$lt' => 20));
Я выбираю поле автора. $ Id, которое является ссылкой на коллекцию авторов.
Затем я помещаю все $ id в массив как таковой:
while ($cursor->hasNext()): $document = $cursor->getNext(); $authorID[] = $document['_id']; endwhile;
и затем я пытаюсь найти правильный номер с этим запросом в коллекции авторов
$query2 = array('age' => array('$gte' => 19, '$lt' =>100), '_id' => array('$in' => $authorID)); $cursor = q('author')->find($query2);
Я пытаюсь получить общее число с этим кодом: $ count = $ cursor-> count (); но независимо от того, какой запрос я пытаюсь запустить, я всегда получаю результат 0 .
Что я делаю неправильно и могу ли вообще создать такой запрос или мне нужно сделать его на уровне приложения вместо уровня базы данных?
И я хорошо знаю встроенные документы, но я хочу, чтобы эти две коллекции были разделены и не вставляли их.
Надеюсь, кто-нибудь может мне помочь.
душевный
– Mestika
Попытка «создать« реляционный »запрос в MongoDB будет упражнением в расстройстве. Ваша схема хранит некоторую информацию (рейтинг публикации) в одной коллекции и другую информацию (возраст автора) в другой коллекции, но все запросы MongoDB работают с отдельными коллекциями. Если вы не денормализуете свои данные (которые, как вы сказали, вы не хотели делать), вам понадобится двухпроходный метод для выполнения этой работы.
Подход, который должен работать, заключается в создании массива идентификаторов авторов и использовании его в запросе коллекции сообщений с использованием «$ in». Вот как это могло бы выглядеть в JavaScript с использованием оболочки mongo:
> var authorList = []; > var authorCursor = db.authors.find({age:{$gt:19,$lt:25}},{"_id":1}); > while(authorCursor.hasNext()){authorList.push(authorCursor.next()["_id"])}; > db.posts.find({"author.$id":{$in:authorList},rating:{$gt:6,$lt:9}});
Первая строка создает пустой массив. Вторая строка создает курсор, который будет выбирать поля _id
всех авторов в вашем целевом возрастном диапазоне. Третья строка использует курсор для заполнения массива author _id
s. В четвертой строке отображаются все сообщения, соответствующие вашим целевым критериям: author _id
в списке, который мы только что создали, и рейтинг в указанном вами диапазоне.
Я не знаю, но иногда, метод курсора, кажется, теряет некоторые элементы, поэтому я предпочитаю использовать toArray ():
u = db.authors.find({"isActive":false}).toArray() idlist = [] u.forEach(function(myDoc) { idlist.push(myDoc.ID ); } ) db.posts.find({"AuthorID": {$in : idlist} } ) u = db.authors.find({"isActive":false}) idlist2 = [] while (u.hasNext()) {idlist2.push(u.next()["ID"])}; idlist.forEach(function(myDoc) { if ( idlist2.indexOf(myDoc) == -1 ) {print (myDoc)} })
напечатайте 20 элементов!