Я построил грамматику (используя peg.js) для поддержки простых поисковых запросов в веб-приложении Node.js; Мне нужно перевести AST, который он выдает, в параметр $match
для агрегатной функции MongoDB. В большинстве случаев все в порядке, но я не могу понять, как NOT (A AND B)
должен выглядеть в MongoDB.
Некоторые примеры данных:
{ _id:123, labels:['a', 'b', 'c'], tags:['g', 'h', 'i']},
{ _id:456, labels:['a', 'e', 'f'], tags:['i', 'j', 'k']},
{ _id:789, labels:['c', 'd', 'b'], tags:['h', 'l', 'm']}
Пользователь может ввести запрос NOT (labels:a AND labels:b)
или NOT (labels:b AND tags:h)
, которые являются действительными запросами, основываясь на моей грамматике.
Цель первого запроса - вернуть все документы, которые не содержат как 'a', так и 'b' в их поле labels
(поэтому будут возвращены второй и третий документы); для второго запроса он должен соответствовать всем документам, которые не содержат как 'b' в поле labels
, так и 'h' в поле tags
.
Оператор $not
MongoDB, похоже, не позволяет вам аккуратно отрицать логическую операцию так, как я ищу; в идеале я хотел бы сделать что-то вроде:
{
$not: {
$and: [
{ labels: a},
{ labels: b},
]
}
}
или
{
$not: {
$and: [
{ labels: b},
{ tags: h},
]
}
}
Есть ли другой оператор, который я могу использовать для этого? Кроме того, в идеале, это было бы легко создать программно, чтобы я мог построить потенциально сложный сложный запрос в скобках, а затем просто отменить его, если было NOT
.
РЕДАКТИРОВАТЬ : Расширил набор данных, расширил и уточнил мои фактические требования к ответу.