Учетная запись MongoDB встроенных и вспомогательных документов

Учитывая приведенные ниже конкурирующие схемы с до 100 000 друзьями, я заинтересован в поиске наиболее эффективных для моих нужд.

Doc1 (Index on user_id)

{
"_id" : "…",
"user_id" : "1",
friends : {
    "2" : {
        "id" : "2",
        "mutuals" : 3
    }
     "3" : {
         "id" : "3",
         "mutuals": "1"
    }
   "4" : {
         "id" : "4",
         "mutuals": "5"
    }
}
}

Doc2 (сложный многозначный индекс на user_id и friends.id)

{
"_id" : "…",
"user_id" : "1",
friends : [
   {
        "id" : "2",
        "mutuals" : 3
    },
    {
         "id" : "3",
         "mutuals": "1"
    },
   {
         "id" : "4",
         "mutuals": "5"
    }
]}

Кажется, я не нашел никакой информации об эффективности поиска в подпоследовательности. Я знаю, что mongo реализует данные внутри BSON, поэтому Im задается вопросом, означает ли это, что проекционный поиск является двоичным O (log n)?

В частности, с учетом user_id, чтобы узнать, существует ли друг с friend_id, как бы два разных запроса в каждой схеме сравнивались? (Предположим вышеприведенные индексы) Обратите внимание, что на самом деле не имеет значения, что вернулось, возвращается только то, что не null, если друг существует.

Doc1col.find({user_id : "…"}, {"friends.friend_id"})
Doc2col.find({user_id : "…", "friends.id" : "friend_id"}, {"_id":1})

Также интересен способ модификации $set. Для схемы 1, учитывая запрос Doc1col.update({user_id : "…"}, {"$set" : {"friends.friend_id.mutuals" : 5}), как работает поиск в friend.friend_id? Является ли это операцией O (log n) (где n - количество друзей)?

Для схемы 2, как бы запрос Doc2col.update({user_id : "…", "friends.id" : "friend_id"}, {"$set": {"friends.$.mutuals" : 5}) сравнивался с запросом выше?

Ответ 1

doc1 предпочтительнее, если одним из основных требований является представление данных в ui в красивом управляемом пакете. его просто отфильтровать только нужные данные с помощью проекции {}, {friends.2 : 1}

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

поверх того, что doc2 разрешает гораздо более чистый синтаксис

db.doc2.findOne({user_id: 1, friends.id : 2} )

против

db.doc1.findOne({ $and : [{ user_id: 1 }, { "friends.2" : {$exists: true} }] })

в заключительной заметке, однако, можно создать разреженный индекс на doc1 (и использовать $exists), но ваша возможность 100 000 друзей - - каждый друг нуждается в разреженном индексе - делает это абсурдным. против разумного числа записей, говорят демографические данные пола [мужчины, женщины], возрастные группы [0-10,11-16,25-30,..] или более impt вещи [gin, whisky, vodka,...]