0

这是我的 Mongo DB 结构的示例文档:

{ _id: 1
  records: [{n: "Name", v: "Kevin"}, 
            {n: "Age", v: "100"}, 
             ..., 
            {n: "Field25", v: "Value25"} ]
}

要搜索所有具有 的文档Name of "Kevin" and an Age of "100",我将$all$elemMatch 一起使用。我需要使用 $elemMatch 来精确匹配 n:"Name" 和 v:"Kevin" 的子文档,以及 $all,因为我正在查询数组

db.collection.find({"records" : { $all: [
                                         {$elemMatch: {n: "Name", v: "Kevin"},
                                         {$elemMatch: {n: "Age", v: "100"}
                                        ]}})

但是,当第一个 $elemMatch 参数是非选择性的时,$all 运算符效率低下,即有许多文档与该字段匹配。

Mongo Docs详细说明:

在当前版本中,使用 $all 运算符的查询必须扫描与查询数组中的第一个元素匹配的所有文档。因此,即使使用索引来支持查询,操作也可能需要长时间运行,特别是当数组中的第一个元素不是很有选择性时。

我的查询有更好的选择吗?

4

2 回答 2

1

我建议对您的结构进行彻底的改变,这将简化查询。抱歉,如果无法进行此更改,但没有更多数据,我认为没有任何问题:

{ _id: 1
  records: [{"Name":"Kevin", 
            "Age":"100", 
             ..., 
            "Field25":"Value25"} ]
}

和查询:

db.collection.find("records":{$elemMatch:{Name:"Kevin","Age":100}})

这将返回所有具有符合上述所有条件的记录的对象(假设有更多记录,例如,如果他们是某个班级的学生)。

但是,如果您只想每个 _id 有一个文档,请忘记记录数组:

{ _id: 1,
 "Name":"Kevin", 
 "Age":"100", 
   ..., 
 "Field25":"Value25"} ]
    }

和查询:

db.collection.find({Name:"Kevin","Age":100})

希望这可以帮助。

于 2013-10-25T21:27:00.973 回答
0

我认为这应该是最好的解决方案。

db.collection.find({},
{
  records: {
    $filter: {
      input: "$records",
      as: "record",
      cond: {
        $or: [
          {
            $eq: [
              "$$record.v",
              "Kevin"
            ]
          },
          {
            $eq: [
              "$$record.v",
              "100"
            ]
          }
        ]
      }
    }
  }
})

解决方案链接:https ://mongoplayground.net/p/aQAw0cG9Ipm

于 2021-10-04T17:46:16.300 回答