2012-04-23 2 views
2

Я пытаюсь создать простую систему блога в PHP с MongoDB, чтобы дать Монго попробовать, но я столкнулся с некоторыми трудностями, связанными с этим.MongoDB: Как запросить вложенные массивы?

Я генерироваться 2000 случайных сообщений, где каждый Блогпост документ выглядит следующим образом:

{ 
    "_id": ObjectId("4f908868d3269edc1a00044c"), 
    "author": { 
    "name": "Christine Skinner", 
    "email": "[email protected]", 
    "age": 54, 
    "city": "London" 
    }, 
    "post": "sagittis. Nullam vitae diam. Proin dolor. Nulla semper tellus id nunc interdum feugiat. Sed nec metus facilisis lorem tristique aliquet. Phasellus fer [...]", 
    "date": "Fri Nov 13 12: 11: 48 +0100 2009", 
    "rating": 2, 
    "comments": { 
    "0": { 
     "name": "Barrett Bailey", 
     "email": "[email protected]", 
     "upVotes": 4, 
     "downVotes": 76, 
     "comment": "gravida. Aliquam tincidunt, nunc ac mattis ornare, lectus ante dictum mi, ac mattis velit justo nec ante. Maecenas mi felis, adipiscing fringilla, por [...]" 
    }, 
    "1": { 
     "name": "Cheryl Fitzgerald", 
     "email": "[email protected]", 
     "upVotes": 13, 
     "downVotes": 76, 
     "comment": "adipiscing. Mauris molestie pharetra nibh. Aliquam ornare, libero at auctor mauris id sapien. Cras dolor dolor, tempus non, lacinia at, iaculis quis, [...]" 
    }, 
    "2": { 
     "name": "Carly Graham", 
     "email": "[email protected]", 
     "upVotes": 55, 
     "downVotes": 75, 
     "comment": "Nullam velit dui, semper et, lacinia vitae, massa lobortis ultrices. Vivamus rhoncus. Donec est. Nunc ullamcorper, velit in aliquet lobortis, nisi nib [...]" 
    } 
    }, 
    "tags": { 
    "0": "World War II", 
    "1": "world War I" 
    } 
} 

Я очень много получаю держание этих более благополучных запросов при получении, например, все сообщения, написанные одним конкретного автора или получение сообщений, где рейтинг больше или равен X, но у меня возникают некоторые проблемы с моим вложенным массивом комментариев.

Я не уверен, что я сделал это неправильно, но как мне в первую очередь отобразить все блоги с комментариями? Когда я делаю простой $collection->find(), я использую функцию PHP iterator_to_array, чтобы получить все это в массиве. Затем я делаю простой foreach() для итерации по каждому значению, но из-за того, что комментарии сами являются массивом. Должен ли я сделать новый foreach, чтобы получить комментарии, или есть более быстрый и разумный способ сделать это?

Еще одна проблема, которая возникает у меня, если я хочу использовать свойства комментариев в запросе. Если мне нужно удалить комментарий, мне нужно создать блог _id и автора комментария (или номер комментария), но количество комментариев варьируется, поэтому иногда есть только один комментарий, а иногда бывает до 10 комментариев.

Следует ли помещать комментарии в другую коллекцию, или я могу получить ее, чтобы дать каждому комментарию более уникальный идентификатор вместо номера массива? И как мне использовать свойства внутри комментариев для запроса, скажем, что я хочу показать одно сообщение в блоге, но отсортировать комментарии после самых больших upVotes?

Я пробовал несколько руководств, но большинство из них имеют дело с очень статическими документами, поэтому мне кажется, что я могу сделать это неправильно?

Любая помощь или предложения очень ценятся.

ответ

4

Во-первых, если вы хотите получить сообщение в блоге со всеми комментариями в нем, вы можете просто сделать что-то вроде:

$collection->find(array('author.name'=>'Christine Skinner')); 

Во-вторых, да, если вы хотите, чтобы отобразить все комментарии, вам нужно другой цикл, так:

foreach ($cursor as $post){ 
    foreach($post['comments'] as $num=>$comment){ 
     echo "Comment number " 
      .$num 
      ." was written by " 
      .$comment['name'] 
      .": " 
      .$comment['comment']; 
    } 
} 

Если вы хотите обновить отдельные комментарии сводного документа, вы можете сделать это так:

$collection->update(
     array('_id'=>new MongoId($id)), 
     array('$set'=>array('comments.'.$num.'.comment'=>$newComment)) 
); 

Вы не сможете сортировать комментарии к поддоку в запросе, поэтому вам нужно будет отсортировать по PHP после запроса, для каждого сообщения, которое вы вернетесь.Взгляните на usort в руководстве по PHP, которое может сделать то, что вам нужно: http://www.php.net/manual/en/function.usort.php.

0

В соответствии с вашим документом вы фактически сохраняете комментарии в поддокументе (объекте), а не в массиве. Таким образом, каждый из ваших комментариев имеет уникальный идентификатор (0-2 в этом случае). Если вы хотите удалить конкретный комментарий было бы так просто, как следующее в консоли:

db.collection.update({"_id": ObjectId("4f908868d3269edc1a00044c")}, {$unset: {"comments.1": 1}}); 

Или в PHP:

$collection->update(array("$unset" => array("comments.1" => 1))); 

Что касается итерации над вашими комментариями, у вас есть это право. В основном вам нужно будет просмотреть элемент комментариев вашего возвращаемого документа.

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