Mongoose, как сортировать по сумме встроенного массива [duplicate]

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

5
задан Blakes Seven 6 October 2015 в 04:48
поделиться

1 ответ

Если вы хотите «весить» результаты по определенным критериям или иметь какое-либо «вычисленное значение» в «сортировке», тогда вам понадобится метод .aggregate() . Это позволяет использовать «прогнозируемые» значения в операции $sort , для которой может использоваться только настоящее поле в документе:

db.messages.aggregate([
    { "$match": { "messages": userId } },
    { "$project": {
        "recipients": 1,
        "unread": 1,
        "content": 1,
        "readYet": {
            "$setIsSubset": [ [userId], "$unread" ] }
        }
    }},
    { "$sort": { "readYet": -1 } },
    { "$limit": 20 }
])

Здесь $setIsSubset позволяет сопоставить «непрочитанный» массив с преобразованным массивом [userId], чтобы увидеть, имеются ли какие-либо совпадения. Результат будет либо true, где существует userId, либо false, где это не так.

Затем это можно передать в $sort, который заказывает результаты с предпочтениями совпадений (сортировка сортировки является true сверху), и, наконец, $limit просто возвращает результаты до указанной суммы.

Итак, чтобы использовать заданный термин для «сортировки», значение должно быть «проецировано» в документ, чтобы его можно было отсортировать. Структура агрегации - это то, как вы это делаете.

Также обратите внимание, что $elemMatch не требуется только для того, чтобы соответствовать одному значению в массиве, и вам нужно только указать значение напрямую. Это цель, где «несколько» условий должны выполняться на одном элементе массива, что, конечно, здесь не применяется.

5
ответ дан Blakes Seven 19 August 2018 в 15:48
поделиться
  • 1
    Это сработало отлично. Спасибо! Единственный комментарий, который я сделаю, это то, что Mongo забросил ошибку, пока я не изменил $ setIsSubSet на $ setIsSubset. – beatniknight 6 October 2015 в 22:24
  • 2
    @beatniknight Типичный я. Ссылка на документацию была правильной, но мой мозг camelCase продолжает говорить, что это два слова и продолжает печатать его таким образом. – Blakes Seven 6 October 2015 в 22:28
  • 3
    Лучше использовать $in вместо $setIsSubset. Итак: "$in": [ userId, "$unread" ] – TechWisdom 5 April 2018 в 10:44
Другие вопросы по тегам:

Похожие вопросы: