2012-05-02 3 views
3

У меня есть две коллекции Должности и авторы. Почтовый документ содержит помимо данных сообщения a DBref link ID _id. Моя коллекция выглядит следующим образом:MongoDB: запрос нескольких коллекций с двумя запросами?

сообщений

"_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" : "[email protected]", 
     "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" : "[email protected]\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)); 

I выбирает $ поле идентификатора автора, который является ссылкой на коллекцию авторов..

Затем я положил все $ идентификаторов в массиве, как например:

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); 

I попробуйте получить общее число с помощью этого кода: $ count = $ cursor-> count(); но независимо от того, какой запрос я пытаюсь запустить, я всегда получаю результат .

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

И я хорошо знаю встроенные документы, но хочу, чтобы эти две коллекции были разделены и не вставлялись в него.

Надеюсь, что кто-нибудь может мне помочь.

Искренней
- Mestika

ответ

5

Попытка «создать„реляционный“запрос» в MongoDB будет упражнением в разочаровании. Ваша схема хранит некоторую информацию (рейтинг публикации) в одной коллекции и другую информацию (возраст автора) в другой коллекции, но все запросы MongoDB работают с отдельными коллекциями. Если вы не денормализуете свои данные (которые, как вы сказали, вы не хотели делать), вам понадобится двухпроходный метод для выполнения этой работы.

Подход, который должен работать, заключается в создании массива идентификаторов авторов и использовании его в запросе коллекции сообщений с использованием «$ in».Вот как это могло бы выглядеть в JavaScript с использованием оболочки манго:

> 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 всех авторов в вашем целевом возрастном диапазоне. Третья строка использует курсор для заполнения массива автора _id. В четвертой строке отображаются все сообщения, соответствующие вашим целевым критериям: автор _id в списке, который мы только что создали и рейтинг в указанном вами диапазоне.

1

я не знаю, но иногда, метод курсора, кажется, теряют некоторые элементы, поэтому я предпочитаю использовать 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 элементов!

 Смежные вопросы

  • Нет связанных вопросов^_^