我有与此类似的对象集合(为了这个问题的目的而简化):

_id: '6509e5f504613ddc1d92c62f',
matchingHistory: [
  {
    color: 'red',
    shape: 'square',
    size: 'large',
    _id: '1509e5f504613ddc1d92c62g',
    updatedAt: '2023-09-21T16:16:00.000Z'
  },
  {
    color: 'red',
    shape: 'square',
    size: 'small',
    _id: '2509e5f504613ddc1d92c62h',
    updatedAt: '2023-09-21T16:10:00.000Z'
  },
]

我想从find查询中排除matchingHistory中没有对象redsquarelarge的所有文档,但所有且只有所有这些条件必须匹配.话虽如此,另外,我想忽略搜索中的特定字段,例如_idupdatedAt.matchingHistory最初未设置,稍后重置时它将变为空数组,因此这些文档应包含在结果中.TLDR;我只想排除对象数组中包含确切对象(红色+正方形+大)的文档.

我try 了$not$nor的多种组合,但都没有产生预期的效果.

我的最后一次try 是在下面,但问题是,它实际上也排除了"red+square+small"(因为它似乎关心"至少"一个属性匹配:

$or: [
  {
    matchingHistory: {
      $exists: true,
      $eq: [],
    },
  },
  {
    matchingHistory: {
      $exists: false,
    },
  },
  {
    $and: [
      {
        matchingHistory.color: {
          $ne: 'red',
        },
      },
      {
        matchingHistory.shape: {
          $ne: 'square',
        },
      },
      {
        matchingHistory.size: {
          $ne: 'large',
        },
      },
    ],
  }
]

推荐答案

这是一个相当简单的发现.想象一下,您want要查找具有matchingHistory的文档,该文档的数组中有一个与{ color: 'red', shape: 'square', size: 'large'}匹配的对象,然后按如下方式求反:

Mongosh Shell

db.collection.find({
  $or: [
    {
      matchingHistory: {
        $exists: true,
        $eq: []
      }
    },
    {
      matchingHistory: {
        $exists: false
      }
    },
    {
      matchingHistory: {
        $not: {              //< All important not
          $elemMatch: {      //< Exact element match
            color: "red",
            shape: "square",
            size: "large"
          }
        }
      }
    }
  ]
}, {'matchingHistory._id': 0, 'matchingHistory.updatedAt': 0 });

Node Driver:

db.collection.find({
  $or: [
    {
      matchingHistory: {
        $exists: true,
        $eq: []
      }
    },
    {
      matchingHistory: {
        $exists: false
      }
    },
    {
      matchingHistory: {
        $not: {              //< All important not
          $elemMatch: {      //< Exact element match
            color: "red",
            shape: "square",
            size: "large"
          }
        }
      }
    }
  ]
}).project({
   'matchingHistory._id': 0, 
   'matchingHistory.updatedAt': 0 
});

Mongodb相关问答推荐

MongoDB - 将对象转换为数组

如何向所有文档添加一个字段,其中前 100 个文档的值为 1,接下来的 100 个文档的值为 2,依此类推?

MongoDB 使用 pymongo 收集 500K 文档的写入速度很差

在 MongoDB 中使用 findOneAndUpdate 有条件地更新/更新嵌入式数组

如何过滤查找mongodb的结果

Mongo查询子文档的多个字段

使用 MongoDB C# 驱动程序在嵌套数组上使用过滤器生成器进行查询

将 mongoose 字符串模式类型默认值设为空白并使该字段可选

无法将 $match 运算符用于带有 ObjectId 的 mongodb/mongoose 聚合

Python - Pymongo 插入和更新文档

在 Postgres JSON 数组中查询

mongodb nodejs - 转换圆形 struct

MongoDB Compass 过滤器(查询)

MongoDB 日志(log)文件和 oplog 有何不同?

我如何使用 Twitter 的流 api 中的推文并将它们存储在 mongodb 中

如何从 Mongoose 模型对象中获取集合名称

填充mongoose后查找

mongoose:按字母顺序排序

如何在 Ubuntu 上安装 mongodb-clients 最新版本?

带有索引字段的 MongoDB 正则表达式