Можно ли отсортировать по элементу во вложенном массиве в Mongo? - PullRequest
5 голосов
/ 06 февраля 2012

Допустим, у меня есть коллекция в mongodb, чьи объекты имеют вложенный массив. Я хочу отсортировать на основе значения конкретного элемента массива. Возможно ли это?

Например, (а я только что составил пример), если у меня есть коллекция типов фильмов (боевик, комедия, мелодрама) и примеры, представленные пользователями, могу ли я найти все объекты, где данный пользователь представлен, отсортированные по дате фильма?

Например, я хотел бы найти все типы, в которых «Аарон» представил пример, отсортированный по году примера «Аарон».

Это почти как пункт "потребность где" в сортировке.

> db.movies.find (). Pretty ();

{
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"),
    "type" : "action",
    "examples" : [
        {
            "title" : "Gladiator",
            "year" : 2000,
            "submitter" : "Aaron"
        },
        {
            "title" : "Mission Impossiple",
            "year" : 1996,
            "submitter" : "Bill"
        },
        {
            "title" : "The Terminator",
            "year" : 1984,
            "submitter" : "Jane"
        }
    ]
}
{
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"),
    "type" : "comedy",
    "examples" : [
        {
            "title" : "The Hangover",
            "year" : 2009,
            "submitter" : "Aaron"
        },
        {
            "title" : "Dogma",
            "year" : 1999,
            "submitter" : "Bill"
        },
        {
            "tile" : "Airplane",
            "year" : 1980,
            "submitter" : "Jane"
        }
    ]
}

> db.movies.find ({'examples.submitter': 'Aaron'}). Sort ({'examples.year': 1}). Pretty ();

{
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"),
    "type" : "comedy",
    "examples" : [
        {
            "title" : "The Hangover",
            "year" : 2009,
            "submitter" : "Aaron"
        },
        {
            "title" : "Dogma",
            "year" : 1999,
            "submitter" : "Bill"
        },
        {
            "tile" : "Airplane",
            "year" : 1980,
            "submitter" : "Jane"
        }
    ]
}
{
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"),
    "type" : "action",
    "examples" : [
        {
            "title" : "Gladiator",
            "year" : 2000,
            "submitter" : "Aaron"
        },
        {
            "title" : "Mission Impossiple",
            "year" : 1996,
            "submitter" : "Bill"
        },
        {
            "title" : "The Terminator",
            "year" : 1984,
            "submitter" : "Jane"
        }
    ]
}

Обратите внимание, что документы возвращаются отсортированными по году коллекций (как и ожидалось). Можно ли отсортировать документы только по тем, которые были предоставлены данным пользователем? для некоторых дополнительных деталей я использую нодный драйвер mongo для nodejs.

Ответы [ 3 ]

5 голосов
/ 06 февраля 2012

... какой-либо способ сортировки только по тем, которые были предоставлены данным пользователем?

Не думаю, что это сработает так, как вы хотите.

В MongoDB запросы возвращают целые документы.Когда вы выполняете следующий запрос, вы находите все документы, где любой отправитель соответствует 'Aaron'.

> db.movies.find({'examples.submitter': 'Aaron'})

. Обратите внимание, что теоретически 'Aaron' может совпадать дважды в одном документе, но возвращать этот документ только один раз.Это усложняет проблему сортировки.

> db.movies.find({'examples.submitter': 'Aaron'}).sort({'examples.year': 1})

Так что вы ожидаете, когда один документ содержит две вещи по 'Aaron' с разными годами?Помните, что мы можем только сортировать документы, мы не можем отсортировать внутренний массив с помощью запроса.

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

Пожалуйста, взгляните на новую Aggregation Framework , которая может предоставить то, что вы ищете.Обратите внимание, что в настоящее время это функция нестабильной ветки.

1 голос
/ 06 ноября 2014

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

{'examples.submitter': 1, 'examples.year': 1}

Если вы заставите свой запрос использовать этот индекс, используя подсказку ("indexname"), ваши результаты будут возвращаться в порядке индекса.

0 голосов
/ 06 февраля 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...