Как сортировать мультиключи MongoDB? - PullRequest
4 голосов
/ 31 января 2012

В MongoDB, поле может иметь несколько значений (массив значений).Каждый из них индексируется, так что вы можете фильтровать по любому из значений.Но можете ли вы также «упорядочить» поле с несколькими значениями и каков результат?

Обновление:

> db.test.find().sort({a:1})
{ "_id" : ObjectId("4f27e36b5eaa9ebfda3c1c53"), "a" : [ 0 ] }
{ "_id" : ObjectId("4f27e3845eaa9ebfda3c1c54"), "a" : [ 0, 1 ] }
{ "_id" : ObjectId("4f27df6e5eaa9ebfda3c1c4c"), "a" : [ 1, 1, 1 ] }
{ "_id" : ObjectId("4f27df735eaa9ebfda3c1c4d"), "a" : [ 1, 1, 2 ] }
{ "_id" : ObjectId("4f27df795eaa9ebfda3c1c4e"), "a" : [ 2, 1, 2 ] }
{ "_id" : ObjectId("4f27df7f5eaa9ebfda3c1c4f"), "a" : [ 2, 2, 1 ] }
{ "_id" : ObjectId("4f27df845eaa9ebfda3c1c50"), "a" : [ 2, 1 ] }
{ "_id" : ObjectId("4f27e39a5eaa9ebfda3c1c55"), "a" : [ 2 ] }

С массивами неравной длиныболее длинный массив «ниже», чем более короткий массив

Итак, почему [0] до [0,1], но [2] после [2,1]?Может быть, сортировка выполняется только по первому элементу массива?Или самый низкий?И после этого это порядок вставки?

Кроме того, как это реализовано в случае сканирования индекса (в отличие от сканирования таблицы)?

1 Ответ

7 голосов
/ 31 января 2012

Сортировка элементов массива довольно сложна. Поскольку элементы массива индексируются отдельно, сортировка по полю массива фактически приведет к некоторым интересным ситуациям. Что происходит, так это то, что MongoDB будет сортировать их по минимальному или максимальному значению в массиве (в зависимости от направления сортировки). Кроме того, порядок естественен.

Это приводит к таким вещам, как:

> db.test.save({a:[1]})
> db.test.save({a:[0,2]})
> db.test.find().sort({a:1})
{ "_id" : ObjectId("4f29026f5b6b8b5fa49df1c3"), "a" : [ 0, 2 ] }
{ "_id" : ObjectId("4f2902695b6b8b5fa49df1c2"), "a" : [ 1 ] }
> db.test.find().sort({a:-1})
{ "_id" : ObjectId("4f29026f5b6b8b5fa49df1c3"), "a" : [ 0, 2 ] }
{ "_id" : ObjectId("4f2902695b6b8b5fa49df1c2"), "a" : [ 1 ] }

Другими словами. Тот же порядок для обращенных сортов. Это связано с тем, что поле «a» верхнего документа содержит как самое низкое, так и самое высокое значение.

Таким образом, для сортировки MongoDB игнорирует все значения в массиве, которые не являются ни самыми высокими (сортировка {field: -1}), ни самыми низкими (сортировка {field: 1}), и упорядочивает оставшиеся значения.

Чтобы нарисовать (упрощенно) картинку, она работает примерно так:

сплющенное b-дерево для индекса {a: 1}, приведенного выше для примеров документов:

"a" value 0 -> document 4f29026f5b6b8b5fa49df1c3
"a" value 1 -> document 4f2902695b6b8b5fa49df1c2
"a" value 2 -> document 4f29026f5b6b8b5fa49df1c3

Как видно, сканирование сверху вниз и снизу вверх приведет к тому же порядку.

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

Индексы не изменяют поведение сортировки массивов.

...