Mongoose 排除数组中包含特定嵌套对象的文档

Mongoose exclude documents that contain specific nested object in array

提问人:lokers 提问时间:9/20/2023 最后编辑:lokers 更新时间:9/21/2023 访问量:77

问:

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

_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'
  },
]

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

我尝试了 的多种组合,但它们没有产生预期的结果。$not$nor

我的最后一次尝试如下,但问题是,它实际上也排除了“红色+正方形+”(因为它似乎关心“至少”一个属性匹配:

$or: [
  {
    matchingHistory: {
      $exists: true,
      $eq: [],
    },
  },
  {
    matchingHistory: {
      $exists: false,
    },
  },
  {
    $and: [
      {
        matchingHistory.color: {
          $ne: 'red',
        },
      },
      {
        matchingHistory.shape: {
          $ne: 'square',
        },
      },
      {
        matchingHistory.size: {
          $ne: 'large',
        },
      },
    ],
  }
]
mongodb mongoose mongodb-query 查找

评论

0赞 ray 9/20/2023
这是你要找的吗?

答:

1赞 jQueeny 9/20/2023 #1

这是一个相当简单的发现。试想一下,你想找到一个文档,它的数组中有一个对象匹配,然后像这样否定它:matchingHistory{ color: 'red', shape: 'square', size: 'large'}

蒙古壳牌

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 });

节点驱动程序:

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 
});

评论

0赞 lokers 9/21/2023
我想我可能应该稍微修改一下我的问题,因为即使你的解决方案非常适合我提出的问题,我忘了提到该对象具有我根本不想关心的其他属性......例如,除了 、 、 之外,它还具有 、 和更多的属性......您知道如何构造查询以使其忽略它们吗?colorshapesize_idupdatedAt
0赞 jQueeny 9/21/2023
所以你不希望这些其他属性输出在返回的文档中,即被抑制?如果是这样,可以在输出投影中完成。如果你需要,我可以举个例子?
0赞 jQueeny 9/21/2023
Node 文档显示使用投影作为链接查找的方法,但 Mongosh 文档显示投影作为 find 方法的第二个参数。我在上面的答案中包括了这两个例子。只需添加要排除的属性即可满足您的需求。
0赞 lokers 9/21/2023
我不想在响应中隐藏任何内容,我想在查询中忽略这些值。像这样: { matchingHistory: { $not: { $elemMatch: { color: “red”, shape: “square”, size: “large”, _id: *, _updatedAt: * } } } }
0赞 lokers 9/21/2023
我将修改我原来的问题以适应这一点