2016-11-05 4 views
0

У меня есть простая музыкальная база данных, содержащая информацию о компакт-дисках (Исполнитель, название альбома, Год выпуска и т. Д.). В принципе, я хочу отсортировать мой запрос с помощью Artist, затем Release Year (что легко сделать), но в случае, если на компакт-диске нет Artist, я хотел бы, чтобы сортировка была нажата в заголовке альбома.Можно ли использовать один вид для нескольких полей в MongoDB?

В качестве примера, для следующих компакт-дисков:

> db.music.find() 
{ "_id" : ObjectId("581d3e073a4d1f0d73a8650b"), "Type" : "CD", "Artist" : "Korn", "Title" : "Korn", "ReleaseYear" : 1994 } 
{ "_id" : ObjectId("581d3e283a4d1f0d73a8650c"), "Type" : "CD", "Artist" : "Korn", "Title" : "Life is Peachy", "ReleaseYear" : 1996 } 
{ "_id" : ObjectId("581d3efd3a4d1f0d73a8650d"), "Type" : "CD", "Title" : "Big Daddy", "ReleaseYear" : 1999 } 
{ "_id" : ObjectId("581d3f3c3a4d1f0d73a8650e"), "Type" : "CD", "Title" : "Aerosmith", "ReleaseYear" : 1973, "Artist" : "Aerosmith" } 

Я хотел бы это рассортированы:

Aerosmith - Aerosmith (1973) 
Big Daddy (1999) 
Korn - Korn (1994) 
Korn - Life is Peachy (1996) 

Вот то, что я пробовал:

> db.music.find().sort({[Artist:1,Title:1],ReleaseYear:1}) 
2016-11-04T22:10:39.317-0400 E QUERY [thread1] SyntaxError: missing ] in computed property name @(shell):1:29 
> db.music.find().sort({[Artist,Title]:1,ReleaseYear:1}) 
2016-11-04T22:10:50.564-0400 E QUERY [thread1] SyntaxError: missing ] in computed property name @(shell):1:29 
> db.music.find().sort({{Artist:1,Title:1},ReleaseYear:1}) 
2016-11-04T22:11:12.040-0400 E QUERY [thread1] SyntaxError: invalid property id @(shell):1:22 

I COULD положить в поле SortName, в котором содержится либо Художник o r Title, но хотелось бы не помещать это в документ напрямую.

ответ

1

Если вы хотите, чтобы сортировка была эффективной на больших наборах данных, и вы обслуживаете запрос в рабочих нагрузках в стиле OLTP, вы можете выбрать материализованный ключ сортировки, так как вы можете поместить индекс для сортировки на нем. Оператор сортировки MongoDB не поддерживает независимые пользовательские ключи сортировки.

Если это нормально для запроса, чтобы потреблять больше времени, например. для аналитики, вы можете использовать MongoDB-х aggregation framework, в частности, два оператора:

  • $project, которая позволяет создавать новые поля в агрегации трубопровода
  • $ifNull, который возвращает ненулевое значение (первый аргумент) или запасной вариант выражение (второй аргумент)

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

db.music.aggregate([ 
    { $project: 
    { "Artist": 1, 
     "Title": 1, 
     "ReleaseYear": 1, 
     "SortName": { "$ifNull" : [ "$Artist", "$Title" ] }, 
    } 
    }, 
    { $sort: { "SortName": 1, "ReleaseYear": 1} } 
]); 

Вы можете добавить любые дополнительные pipeline steps к этому, например, для первого фильтра данных ($match).

+0

Это замечательно! Боюсь, что где-то есть небольшая ошибка. Я получаю «Объект спецификации этапа конвейера должен содержать ровно одно поле». Если я вывожу ', $ sort: {}', я получаю нужный набор данных с новым полем 'SortName'. –

+0

Ах, похоже, что '$ project' и' $ sort' должны быть отдельными элементами в совокупном массиве. С этим он отлично работает! –

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