2015-11-30 2 views
0

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

Текущая база данных содержит более 60 ГБ данных, хранящихся в базе данных MySQL. Теперь я переписываю его в базу данных mongodb, и после извлечения 1 миллиона сообщений (1 сообщение = 1 документ) find() начал занимать некоторое время.

Структура документа как таковой:

{ 
    "_id" : ObjectId(), 
    "message": "<p>Hai guys</p>", 
    "pseudo" : "mahnickname", //from a nickname (*pseudo* in my db) 
    "ancre" : "774497928", //its id in the forum 
    "datepost" : "30/11/2015 20:57:44" 
} 

Я установить идентификатор Анкр, как уникальный, так что я не получаю в два раза один и тот же вход.

Затем пользователь вводит псевдоним и находит все документы, имеющие этот псевдоним.

Вот запрос:

Model.find({pseudo: "danickname"}).sort('-datepost').skip((r_page -1) * 20).limit(20).exec(function(err, bears)... 

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

Я использовал первый метод с MySQL, и это не так долго.

Редактировать: Или, может быть, мне нужно просто индексировать ники (pseudo)?

Спасибо!

+0

Вы должны добавить индекс в 'pseudo'. Оформить этот пост здесь, в частности, области избирательности: http://stackoverflow.com/questions/33545339/how-does-the-order-of-compound-indexes-matter-in-mongodb-performance-wise/33546159 # 33546159 – inspired

+0

Обратите внимание, что 'skip' фактически должен анализировать файлы, которые он пропускает, поэтому, если' r_page' действительно большой, то 'skip' нужно будет перепрыгнуть через кучу документов. –

+0

Ahah Я полностью забыл об индексировании прозвища. Спасибо, я попробую сейчас. – Sinequanon

ответ

1

Вот некоторые рекомендации для вашей задачи о больших данных:

  1. The ObjectId already contains a timestamp. You can also sort on it. Вы можете сэкономить место на диске, удалив поле datepost.
  2. Вам абсолютно необходимо поле ancre? ObjectId уже уникален и проиндексирован. Если вам это абсолютно необходимо, и вам необходимо оставить datepost отдельно, вы можете заменить поле _id полем ancre.
  3. Как уже упоминалось, вы должны добавить индекс на pseudo. Это приведет к тому, что «получить все сообщения, где псевдо-mahnickname» будет искать гораздо быстрее.
  4. Если количество сообщений на пользователя низкое, вы можете сохранить их все в одном документе на одного пользователя. Это позволит избежать перехода на определенную страницу, которая может быть медленной. Однако имейте в виду 16mb limit. Я лично все еще имел бы их в нескольких документах.
  5. Чтобы поддерживать скорость быстрого запроса, убедитесь, что все ваши indexed fields fit in RAM. Вы можете увидеть потребление ОЗУ индексированных полей, введя db.collection.stats() и глядя на под-документ indexSizes.
  6. Будет ли у вас возможность не пропускать документы, но использовать время, которое оно было записано в базу данных в качестве ваших страниц? Если это так, используйте поле datepost или метку времени в _id для вашей стратегии поискового вызова. Если вы решите использовать datepost, сделайте compound index на pseudo и datepost.

Что касается ваших контрольных показателей, вы можете внимательно следить за MongoDB, используя mongotop и mongostat.

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