MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Най-ефективният начин за съхраняване на вложени категории (или йерархични данни) в Mongo?

Първото нещо, което искате да решите, е какъв точно вид дърво ще използвате.

Голямото нещо, което трябва да имате предвид, са вашите данни и модели на достъп. Вече заявихте, че 90% от цялата ви работа ще бъде отправяне на заявки и според това (електронна търговия) актуализациите ще се управляват само от администратори, най-вероятно рядко.

Така че вие ​​искате схема, която ви дава силата да правите заявки бързо за дете през път, т.е.:Спорт -> Баскетбол -> Мъже, Спорт -> Тенис -> Жени, и всъщност не се нуждае от наистина мащабиране към актуализации.

Както правилно посочихте, MongoDB има добра страница с документация за това:https://docs.mongodb.com/manual/applications/data-models-tree-structures/ при което 10gen всъщност посочва различни модели и методи на схеми за дървета и описва основните им възходи и падения.

Това, което трябва да хване окото, ако искате да правите заявки лесно, са материализираните пътища:https://docs.mongodb.com/manual/tutorial/model-tree-structures-with-materialized-paths/

Това е много интересен метод за изграждане на дървета, тъй като за заявка по примера, който сте дали по-горе, в „Жени“ в „Тенис“, можете просто да направите предварително фиксиран регулярен израз (който може да използва индекса:http://docs.mongodb.org/manual/reference/operator/regex/ ) така:

db.products.find({category: /^Sports,Tennis,Womens[,]/})

за да намерите всички продукти, изброени под определен път от вашето дърво.

За съжаление този модел е наистина лош за актуализиране, ако преместите категория или промените името й, трябва да актуализирате всички продукти и може да има хиляди продукти в една категория.

По-добър метод би бил да поставите cat_id върху продукта и след това отделете категориите в отделна колекция със схемата:

{
    _id: ObjectId(),
    name: 'Women\'s',
    path: 'Sports,Tennis,Womens',
    normed_name: 'all_special_chars_and_spaces_and_case_senstive_letters_taken_out_like_this'
}

Така че сега вашите заявки включват само колекцията от категории, което трябва да ги направи много по-малки и по-ефективни. Изключение от това е, когато изтриете категория, продуктите пак ще се нуждаят от докосване.

И така, пример за промяна на „Тенис“ на „Бадмин“:

db.categories.update({path:/^Sports,Tennis[,]/}).forEach(function(doc){
    doc.path = doc.path.replace(/,Tennis/, ",Badmin");
    db.categories.save(doc);
});

За съжаление MongoDB в момента не предоставя отражение на документа в заявката, така че трябва да ги изтеглите от страна на клиента, което е малко досадно, но се надяваме, че не трябва да доведе до връщане на твърде много категории.

И това е основно как работи наистина. Актуализирането е малко болезнено, но силата на възможността да правите незабавни заявки по всеки път, използвайки индекс, е по-подходяща за вашия сценарий според мен.

Разбира се, допълнителното предимство е, че тази схема е съвместима с модели на вложен набор:http://en.wikipedia .org/wiki/Nested_set_model които откривам отново и отново, са просто страхотни за сайтове за електронна търговия, например тенисът може да е както в „Спорт“, така и в „Свободно време“ и искате множество пътища в зависимост от това откъде идва потребителят.

Схемата за материализирани пътища лесно поддържа това чрез просто добавяне на друг path , толкова просто.

Надяваме се, че има смисъл, доста дълго.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mongo моделиране на данни/актуализации за гласуване (нагоре и надолу)

  2. Не може да се създаде резервен mongodump с --db. Неуспешна идентификация

  3. Mongo агрегиране срещу Java за цикъл и производителност

  4. Spring Data mongo за вмъкване на нулеви стойности в DB

  5. Как да настроя MongoDB база данни на Heroku с MongoLab?