0

我想从 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,
            
             }
 ] 
}

我该如何解决这个问题?

4

1 回答 1

1

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

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

查询文档应该只包含一个关于正在投影的数组字段的条件。多个条件可能会在内部相互覆盖并导致未定义的行为。

源 -数组字段限制

在您的查询中,

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 }
);
于 2020-06-26T12:29:32.170 回答