2013-07-16 2 views
3

Введение/МерыСлучайной MongoDB Запись

Я работаю с базой данных MongoDB с 10 Гб записей (около 3 миллионов записей).

Каждая запись (документ) имеет поле под названием DomainClass (которое является одним из 11 разных классов, ранее определенных нами).

Что я пытаюсь выполнить

По соображениям статистики, я должен извлечь из этой базы данных, 100 records of each type of DomainClass, и я не могу просто получить первые 100, поскольку выборка будет смещена. Мне нужно, чтобы эти 100 записей были рандомизированы в базе данных.

Что я пробовал:

Это в основном то, что я попробовал (в C#).

1 - Подсчитайте количество записей, относящихся к определенному DomainClass.

2 - Перемешайте 100 чисел от 0 до подсчета

3- Найти все записи, которые принадлежат к этому DomainClass

4- Поместите их в памяти, как список

5 - Использование все ранее рандомизированные целые числа (100) в качестве индекса в этот список (для решения проблемы рандомизации).

Дефекты

Боюсь, что я не в состоянии выделить достаточно памяти (RAM) для всех записей одного класса. Так как мне нужно записи, чтобы быть в случайных позициях в базе данных, я должен поместить их в памяти для того, чтобы быть в состоянии фактически генерирования полностью рандомизированной выборку

Соображения

У меня нет случайного поля в документы. Моей лучшая ставкой является Date поля документа, который следует так:

"CreationDate" : ISODate("2013-06-25T22:43:15.571Z") 

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

Заранее благодарю вас, если есть какая-либо другая информация, которую я должен предоставить.

+0

Зачем вам помещать всю базу данных в память? Просто найдите случайные числа и запросите базу данных, чтобы получить конкретный документ. – Schaliasos

+0

Не вся база данных. Но все документы определенного DomainClass в моем случае. Как я могу запросить конкретный документ, если мне нужны случайные документы каждого класса? Я не думаю, что вы поняли мою проблему –

+0

Хм, что нижеприведенный ниже не лучший способ получить случайную запись, на самом деле это действительно медленный путь; есть много ссылок на google для dong this – Sammaye

ответ

3

Мой подход был бы:

  1. Получить все случайные числа, которые будут ссылаться на документ (не элемент в списке)
  2. Выполните следующий запрос для каждого случайного:

    db.collection.find().пропустить (случайный) .limit (1);

Редактировать

Для каждого DomainClass:

var count = db.collection.find({DomainClass: "aClass"}).count(); 
var random = Math.floor(Math.random() * count); 
var randomDoc = db.collection.find({DomainClass: "aClass"}).skip(random).limit(1); 

Поместите это в петлю, и я думаю, что это решит вашу проблему.

Моей целью является использование skip и limit и получение случайного документа непосредственно из базы данных. Поскольку вы хотите их в произвольном порядке (сортировка не производится), они будут иметь тот же порядок, что и в вашем списке. Пропуск и лимит дают вам тот же результат, что и DomainClassList.ElementAt(index) на стороне клиента.

+0

Это приведет к простой случайной записи из базы данных, а не к случайной записи определенного DomainClass. Допустим, что мои доменные классы - это A, B, C и D. Мне нужно 100 документов, которые звонят классу A, 100 в класс B и т. Д. –

+1

@MarcelloGrechiLins снова проверьте. Я думаю, что это проще, если вы это сделаете. – Schaliasos

+0

Оригинальный вопрос был в C#. Skip ожидает целое число, а количество документов - как длинное. Таким образом, случайные документы будут только внутри первой части Int32 Max вашей коллекции – Dorival