mongo 查找数组中至少有一项不在另一项中的文档

mongo find documents where at least one item from an array is not in the other

我在 mongo 中遇到了这个问题,我想在其中进行查询(常规 mongo 查询,使用终端)以查找字段为空或具有的所有文档至少有一个值与一组正则表达式不匹配。

我的文档具有以下模式:

{
  "id": "20",
  "array": ["abc123", "abc456", "def123", "ghi123"]
}

{
  "id": "21",
  "array": ["abc123", "abc456", "def123"]
}

我用来匹配它们的数组看起来像这样:

[new RegExp(abc), new RegExp(def)]

查询的结果应该只是第一个文档,因为这个包含 "ghi123",它与数组中的任何正则表达式都不匹配。

我知道有 $all、$elementMatch、$in 等运算符可以构建此查询,但到目前为止,我还没有找到正确的解决方案,而且我已经被困了很长一段时间.. . 我发现了其他 Whosebug 页面,这些页面对我很有用,可能会得出正确的答案,但我还不能将其应用到我的问题中。这个似乎最有用:

Check if every element in array matches condition

有人知道如何解决这个问题吗?

这实际上只是一个正则表达式问题,因为所有逻辑都可以在那里处理:

db.collection.find({ "array": /^(?!abc|def)/ })

这基本上只是一个否定断言,即被测试的元素匹配由 | 分隔的任一条件,这意味着 .

由于第一个文档是唯一具有不满足条件的数组元素的文档,因此它是唯一会在此处评估为真的情况。

正则表达式通常由基数 "string" 构建,因此考虑到 "list" 的以下表示形式,这应该不难理解:

var args = ["abc","def"];

var exp = "^(?!" + args.join("|") + ")";
db.collection.find({ "array": new Regexp(exp) });

甚至:

var args = ["abc","def"];
var inclause = { "$in": [ ] };

inclause["$in"] = args.map(function(arg) {
    return new Regexp( "^(?" + arg + ")" );
});

db.collection.find({ "array": inclause });

但第一种形式通常应该更有效率。