使用 elemMatch 从 MongoDB 中的 Array 获取数据



我在产品集合中有以下文档。

db.product.find()
{ "_id" : 1, "results" : [ { "product" : "abc", "score" : 10 }, { "product" : "xyz", "score" : 5 } ] }
{ "_id" : 2, "results" : [ { "product" : "abc", "score" : 8 }, { "product" : "xyz", "score" : 7 } ] }
{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, { "product" : "xyz", "score" : 8 } ] }

以下查询使用 elemMatch 按预期返回结果。

> db.product.find(  {  results :  { $elemMatch :   { product : "xyz" , score : { $eq : 5}  }  } }   )
{ "_id" : 1, "results" : [ { "product" : "abc", "score" : 10 }, { "product" : "xyz", "score" : 5 } ] }

同样,这也返回预期的结果。

> db.product.find(  {  results :  {    product : "xyz" , score : 5  }   }   )
{ "_id" : 1, "results" : [ { "product" : "abc", "score" : 10 }, { "product" : "xyz", "score" : 5 } ] }

但是当我在数组中使用比较运算符时,我没有得到任何结果。

db.product.find(  {  results :  {    product : "xyz" , score : { $eq : 5}  }   }   )

我无法弄清楚这种意外行为。

有两种方法可以进行查询:传递子文档和使用点表示法。

若要查询嵌套字段,应使用点表示法。这意味着您需要执行以下操作:

db.test.find({"results.product": "xyz", "results.score": {$eq : 5}})

如果你像你一样传递一个子文档,那么mongoDB会做完全匹配。这意味着不应该有任何额外的属性,基本上在您的情况下,它期望分数为 {"$eq" : 5}(字面意思是名为 $eq 的属性(

有关更多信息,请查看此答案和文档。

我已经对所有 4 个命令运行了解释。以下是mongoDB在内部创建的过滤器:

db.product.find({ results : { product : "xyz" , score : 5  }   }).explain()
"filter" : {
                "results" : {
                    "$eq" : {
                        "product" : "xyz",
                        "score" : 5
                    }
                }
            }

db.product.find({ "results.product" : "xyz" , "results.score" : 5   }).explain()
      "filter" : {
                    "$and" : [
                        {
                            "results.product" : {
                                "$eq" : "xyz"
                            }
                        },
                        {
                            "results.score" : {
                                "$eq" : 5
                            }
                        }
                    ]
                }
db.product.find(  {  results :  { $elemMatch :   { product : "xyz" , score : { $eq : 5}  }  } }   ).explain()
          "filter" : {
                        "results" : {
                            "$elemMatch" : {
                                "$and" : [
                                    {
                                        "product" : {
                                            "$eq" : "xyz"
                                        }
                                    },
                                    {
                                        "score" : {
                                            "$eq" : 5
                                        }
                                    }
                                ]
                            }
                  }
                }
db.product.find(  {  results :  {    product : "xyz" , score : { $eq : 5}  }   }   ).explain()
                    "filter" : {
                                "results" : {
                                    "$eq" : {
                                        "product" : "xyz",
                                        "score" : {
                                            "$eq" : 5
                                        }
                                    }
                                }
                            }

最新更新