尝试使用findOne从MongoDB中选择单个记录,在嵌套数组中搜索值

whhtz7ly  于 2023-06-22  发布在  Go
关注(0)|答案(2)|浏览(132)

我在MongoDB(6.0.2社区版)中有一个名为VS_Logs的集合。这里有一个对象数组,看起来有点像这样:

Lookups: [
{ REG: "ABC", .... // other stuff},
{ REG: "123", .... // other stuff} etc...
]

我正在尝试从REG = ABC的查找中选择对象。
我试过这个:

db.VS_Logs.findOne({"Lookups" : {$elemMatch: {"REG": "ABC" }}})
db.VS_Logs.find({"Lookups" : {$elemMatch: {"REG": "ABC" }}})

这两种方法都返回所有记录。
我也试过:

db.VS_Logs.findOne({"Lookups.REG": "ABC"})
db.VS_Logs.find({"Lookups.REG": "ABC"})

结果一样。我做错了什么?

jyztefdp

jyztefdp1#

db.VS_Logs.find({"Lookups.REG": "ABC"})
此查询将检索数据库中的所有文档,其中Lookups数组中至少有一个对象的REG属性设置为AB。数组中是否有其他不满足此条件的对象并不重要。
而不是整个文档,如果您试图只选择Lookups数组中的那些对象,其中REG = ABC。试试这个

db.collection.aggregate([
  {
    $project: {
      matchingLookups: {
        $filter: {
          input: "$Lookups",
          as: "lookup",
          cond: {
            $eq: [
              "$$lookup.REG",
              "ABC"
            ]
          }
        }
      }
    }
  }
])

此聚合管道将返回带有名为matchingLookups的数组的文档,该数组仅包含Lookups数组中的对象,其中REG属性设置为ABC。结果看起来有点像这样,

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "matchingLookups": [
      {
        "REG": "ABC"
      }
    ]
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "matchingLookups": []
  }
]

供参考:https://mongoplayground.net/p/8C9Rz1rT0Zh

but5z9lq

but5z9lq2#

这不一定要在聚合中完成。特别是如果matchingLookups字段是您唯一感兴趣的字段(或者其他字段很少),那么如果您愿意,可以使用find()来执行此操作:

db.collection.find({
  "Lookups.REG": "ABC"
},
{
  Lookups: {
    $filter: {
      input: "$Lookups",
      as: "lookup",
      cond: {
        $eq: [
          "$$lookup.REG",
          "ABC"
        ]
      }
    }
  }
})

请注意,我保留并简化了命令的查询部分。这将导致只返回具有匹配项的文档(而不是返回空列表的某些文档)。该字段上的索引还将允许命令有效地执行。
如果您确实需要更多字段,那么最好使用聚合,将$project stage交换为$addFields。如果需要的话,最好还是在它前面加上一个$match来过滤文档(在过滤文档中的数组之前)。
Playground demonstration here

相关问题