如何从 nodejs mongodb 本机驱动程序中的嵌入式文档中查找单个元素?

How to find the single element from embedded document in nodejs mongodb native driver?

我想从 MongoDB 中的嵌入文档中查找单个元素。 这是我在 MongoDB 中收集的用户文档:-

[
       {
         "userId":"001",
        "userName":"abc"
        "subscriptionDetails" : [
            {
            "planId" : "1",
            "isExpired" : false,
            "current" : true,
            "timeStamp" : 1592570927981,
            
            },
            {
            "planId" : "2",
            "isExpired" : false,
            "current" : true,
            "timeStamp" : 1592570927909,
            
             },
            {
            "planId" : "3",
            "isExpired" : false,
            "current" : false,
            "timeStamp" : 1592570978,
            
             }

         ]
     },
    {
        "userId":"002",
        "userName":"abc"
        "subscriptionDetails" : [
            {
            "planId" : "1",
            "isExpired" : false,
            "current" : true,
            "timeStamp" : 1592570927981,
            
            }

         ]
     }
]

我的 nodejs 函数通过 nodejs 本机驱动程序从嵌入式文档中查找单个元素:-

var Plan=await db.collection("user").findOne(
        {
             userId:001,
            'subscriptionDetails.current':false,
            'subscriptionDetails.isExpired':false
            
        },
        {
                'projection':{ "_id": 0,'subscriptionDetails.$':1 }
        }
        )
console.log(plan)

但是这个函数的响应是:-

{ 
 subscriptionDetails: 
   [  {
            "planId" : "1",
            "isExpired" : false,
            "current" : true,
            "timeStamp" : 1592570927981,
            
      }
 ] 
}

但预期的输出是:-

{ 
 subscriptionDetails: 
   [    {
            "planId" : "3",
            "isExpired" : false,
            "current" : false,
            "timeStamp" : 1592570978,
            
             }
 ] 
}

我该如何解决这个问题?

为什么查询没有按预期工作?

使用位置运算符$进行查询结果投影时有一定的限制。其中之一是:

The query document should only contain a single condition on the array field being projected. Multiple conditions may override each other internally and lead to undefined behavior.

来源 - Array fields limitations

在您的查询中,

db.collection("user").findOne(
  {
    userId:001,
    'subscriptionDetails.current':false,
    'subscriptionDetails.isExpired':false
  },
  {
    'projection':{ "_id": 0,'subscriptionDetails.$':1 }
  }
)

您在投影的数组字段上有 2 个条件。这就是查询结果不是预期结果的原因。

修正:

简单的解决方法是将 subscriptionDetails 上的过滤条件减少到一个。但是,如果减少过滤条件不是一个选项,您可以使用 $elemMatch 来组合过滤条件。 $elemMatch 会将 subscriptionDetails 数组的内容限制为仅包含与指定条件匹配的第一个元素。像这样:

db.collection("user").findOne(
  { 
    userId: "001", 
    subscriptionDetails: {
      $elemMatch: {
        current: false,
        isExpired: false,
      }
    } 
  },
  { _id: 0, 'subscriptionDetails.$':1 }
);