После того, как я недавно столкнулся с той же проблемой, я придумал следующее решение:
Сначала найдите все ItemTags, где tagName либо «смешно», либо «политика» и возвращает массив ItemTag _ids.
Затем найдите элементы, которые содержат все ItemTag _ids в массиве тегов
ItemTag
.find({ tagName : { $in : ['funny','politics'] } })
.lean()
.distinct('_id')
.exec((err, itemTagIds) => {
if (err) { console.error(err); }
Item.find({ tag: { $all: itemTagIds} }, (err, items) => {
console.log(items); // Items filtered by tagName
});
});
Есть более фундаментальный вопрос, который здесь не задают: что на самом деле делают эти операторы CASE
?
Забудьте на минуту о производительности. Если CASE
используется только для преобразования окончательного вывода запроса, и фактически можно заменить ту же функциональность на , если
или выберите регистр
в ASP , то это, вероятно, означает, что запрос / процедура базы данных пытается делать то, за что должен отвечать пользовательский интерфейс, например, форматирование. Проблема разделения ответственности более серьезна, чем любая возможная проблема производительности.
Если у вас есть такой запрос:
SELECT InvoiceID, InvoiceDate,
CASE WHEN PaidStatus = 0 THEN 'Unpaid' ELSE 'Paid' END
FROM ...
Это просто глупо, потому что пользовательский интерфейс или любой другой уровень, выполняющий отображение данных в домен, должен знать, как преобразовать статус в базе данных в соответствующее описание. Нет смысла включать эту логику в сам запрос.
С другой стороны, если конструкция CASE
является важной частью запроса, например:
SELECT
SUM(CASE WHEN PaidStatus = 0 THEN Amount ELSE 0 END) AS TotalUnpaid,
SUM(CASE WHEN PaidStatus = 1 THEN Amount ELSE 0 END) AS TotalPaid
FROM ...
Даже не пытайтесь перенести такую логику в пользовательский интерфейс, потому что база данных намного лучше. И CASE
семантически является частью запроса («вычислить общие оплаченные и невыплаченные суммы для x »), он не берет на себя никаких функций пользовательского интерфейса.
Сначала позаботьтесь о том, где на самом деле принадлежит логика, исходя из того, чего она намеревается достичь.Вопросы производительности следует обсуждать только в том случае, если вы действительно замечаете значительные проблемы с производительностью .
По моему опыту, наши серверы баз данных НАМНОГО больше, чем наши серверы приложений, и обычно простаивают менее 30%. Попросите базу данных управлять данными, а затем попросите клиента выполнить итерацию набора результатов. Лучше, чтобы база данных возвращала только те данные, которые вам нужны (если вы можете определить это заранее).
Операторы CASE
предпочтительны, потому что:
Вы должны запросить (отфильтровать и отсортировать) данные в базе данных и оставить представление на уровне представления. Это вызвано двумя ключевыми причинами: