2013-10-15 3 views
0

Я знаю, что при использовании find() в коллекции я могу использовать $ orderBy. Но моя коллекция содержит другие объекты, как я могу отсортировать эти объекты? Например:MongoDB find() заказать дочерние объекты

books: [{ 
    title: 'book 1', 
    authors: [ 
    { name: 'jim' }, 
    { name: 'bob' }, 
    ] 
}, { 
    title: 'book 2', 
    authors: [ 
    { name: 'steve' }, 
    { name: 'joe' }, 
    ] 
}]; 

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

+0

'$ orderBy' работает на уровне курсора, поэтому изменяется только порядок, в котором курсор возвращает соответствующие документы. Лучше всего сортировать массив в каждом документе при его сохранении или обновлении - см. Мой ответ ниже. – SuperAce99

ответ

2

Хитрость заключается в сортировке документов во время записи, а не в режиме чтения.

Как указано, вы просите MongoDB изменить документы до того, как они достигнут вашего приложения. Mongo не любит изменять документы без определенной команды. Основными параметрами для этого являются агрегация, уменьшение карты и прогнозирование. Ни одна из них не особенно подходит для вашей проблемы:

  • Агрегация, вероятно, сложнее, чем вам нужно, см. Другой ответ для опции здесь.
  • Карта Сокращение подобно агрегации, но сложнее.
  • Query-time Projection может фильтровать возвращенные поля, но сортировки нет.

Вместо этого храните документы так, как вы хотите их получить. Когда вы сначала пишете или обновляете документы, используйте оператор обновления массива $sort в массиве authors. Сохраненный BSON object сохранит порядок, поэтому массив будет отсортирован, когда документ будет извлечен.

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

1

Я не совсем уверен, что вам нужно. MongoDB возвращает полные документы, поэтому список авторов всех книг нужно было бы скомпилировать на стороне клиента или использовать aggregation framework.Это не может быть сделано с использованием простого запроса, потому что для операции сортировки требуется проекция.

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

Используя структуру агрегации, вы можете сделать это:

db.books.aggregate(
    {"$unwind" : "$authors"},    // unwind the array 
    {$group : {"_id" : "$authors.name"} }, // distinct 
    {$sort : {"_id" : 1}});    // the actual sort 
+0

Это не фактическая схема, которую я использую, она упрощенная для использования. То, что я пытаюсь сделать, это вернуть сборник книг, отсортированный по названию книги. Коллекция также содержит авторов, которые я хочу отсортировать по имени. Я могу сделать это в javascript после того, как я их извлечу, но я хотел знать, есть ли способ сначала отсортировать их с запросом. –

+0

Как я уже сказал, MongoDB возвращает документы, и вам нужно будет два совершенно разных списка - это невозможно вернуть, потому что в результате вы должны получить два курсора. Тогда вопрос будет заключаться в том, что если использовать структуру агрегации или сделать сортировку на стороне клиента быстрее, возможно, это зависит от вашего варианта использования. Или вам нужен только список авторов в книге, отсортированной? – mnemosyn

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