2013-09-16 8 views
1

Самый простой способ получить все документы из уникальной коллекции, основанной на одном поле.Mongo найти уникальные результаты

Я знаю, что могу использовать db.collections.distrinct для получения массива всех различных значений поля, но я хочу получить первый (или действительно любой) документ для каждого отдельного значения одного поля.

например. если база данных содержала:

{number:1, data:'Test 1'} 
{number:1, data:'This is something else'} 
{number:2, data:'I'm bad at examples'} 
{number:3, data:'I guess there\'s room for one more'} 

он вернется бы (на основе number является уникальным:

{number:1, data:'Test 1'} 
{number:2, data:'I'm bad at examples'} 
{number:3, data:'I guess there\'s room for one more'} 

Edit: Я хотел бы добавить, что сервер не работает Монго 2.0.8 так что нет агрегации и есть больше результатов чем группа поддержки.

+1

Обновление до 2.4 и использовать агрегирование :) – Philipp

+0

использования «отчетливый» запрос –

+0

Вы можете обнаружить, что агрегированные результаты, даже если они были поддержаны на версии, которую вы используете, может не поддерживать размер набора результатов, который вам нужен. – WiredPrairie

ответ

2

Обновление до 2.4 и использования агрегирования :)

Когда вам действительно нужно придерживаться старой версии MongoDB из-за слишком большое количество повторно d, вы можете использовать MapReduce.

В MapReduce функция карты преобразует каждый документ коллекции в новый документ и отличительный ключ. Функция уменьшения используется для объединения документов с одним ключом distincitve в один.

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

var mapFunction = function(document) { 
     emit(document.number, document); 
} 

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

var reduceFunction = function(key, documents) { 
    return documents[0]; 
} 

К сожалению, MapReduce имеет некоторые проблемы. Он не может использовать индексы, поэтому по крайней мере две функции javascript выполняются для каждого отдельного документа в коллекциях (его можно ограничить предварительным исключением некоторых документов с аргументом запроса командой mapReduce). Когда у вас большая коллекция, это может занять некоторое время. Вы также не можете полностью контролировать, как формируются документы, созданные MapReduce. У них всегда есть два поля: _id с ключом и value с документом, который вы вернули для ключа.

MapReduce также трудно отладить устранение неполадок.

ТЛ; др: Обновление до 2,4

+0

Спасибо за создание mapreduce для меня. Похоже, мне все равно придется выполнить некоторую пост-обработку, чтобы переформатировать возвращенные документы. Модернизация определенно находится в списке задач. –

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