Как бы вы эффективно реализовали эти запросы в MongoDB? - PullRequest
6 голосов
/ 15 сентября 2010

Ссылки имеют один или несколько тегов, поэтому на первый взгляд может показаться естественным встроить теги:

link = { title: 'How would you implement these queries efficiently in MongoDB?'
         url: 'http://stackoverflow.com/questions/3720972'
         tags: ['ruby', 'mongodb', 'database-schema', 'database-design', 'nosql']}

Как эти запросы будут эффективно реализованы?

  • Получить ссылкикоторые содержат один или несколько заданных тегов (для поиска ссылок с заданными тегами)
  • Получить список всех тегов без повторения (для автозаполнения окна поиска)
  • Получить самые популярные теги (дляотобразить 10 лучших тегов или облако тегов)

Идея представления ссылки, как указано выше, основана на презентации MongoNY , слайд 38.

Ответы [ 2 ]

4 голосов
/ 15 сентября 2010

Получить ссылки, содержащие тег «value»:

db.col.find({tags: "value"});

Получить ссылки, содержащие теги «val1», «val2»:

db.col.find({tags: { $all : [ "val1", "val2" ] }});

Получить список всех тегов без повторения:

db.col.distinct("tags");

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

Обновление : предлагаемое решение для функции популярности.Попробуйте добавить следующую коллекцию, назовем ее тегами.

doc = {tag: String, pop: Integer}

теперь, когда вы выполняете запрос, вы собираете все показанные теги (этиможет быть агрегировано и выполнено асинхронно) поэтому предположим, что в итоге вы получите следующие теги: «tag1», «tag2», «tag3».

Затем вы вызываете метод update и увеличиваете значение поля pop:

db.tags.update({tag: { $in: ["tag1", "tag2", "tag3"] }}, { $inc: { pop: 1 }});
0 голосов
/ 16 ноября 2010

Вы также можете использовать $ addToSet для изменения массива тегов вместо $ push. Это не изменяет документ, когда тег уже существует. Это будет немного эффективнее, если вы будете часто изменять свои теги (так как документы не будут так сильно расти). Вот пример:

> db.tst_tags.remove()
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag1'}}, true)
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag1'}}, true)
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag2'}}, true)
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag2'}}, true)
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag3'}}, true)
> db.tst_tags.find()
{ "_id" : ObjectId("4ce244548736000000003c6f"), "name" : "test", 
  "tags" : [ "tag1", "tag2", "tag3" ] }
...