MongoDB查询中forEach函数中未定义的值

MongoDB查询中forEach函数中未定义的值,mongodb,mongodb-query,Mongodb,Mongodb Query,这是我的文件: { "CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"), "DeviceId" : "89984320001499681816", "UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"), "FirstName" : " ", "LastName" : "", } { "_id" : "89984320001499681816" } 我的一些文件,名字

这是我的文件:

{
"CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"),
"DeviceId" : "89984320001499681816",
"UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"),
"FirstName" : " ",
"LastName" : "",
}
{
    "_id" : "89984320001499681816"
}
我的一些文件,名字和姓氏都填好了。但所有文档都有DeviceId

我编写这个查询,希望将一个对象传递给一个名已填充的方法

db.location.aggregate([
 {$match : {
     FirstName : 
         {$nin : [" "]}
            }
  },
 {$group: {_id : "$DeviceId" }
 },{
 $project: {
     "DeviceId" : 1
 }}
 ]).forEach(
  function(obj)
    {
      print(
      "Orginal Coll \nDeviceId: " + obj.DeviceId
      +" \nFirstName: "   + obj.FirstName
      +" \nLastName: "    + obj.LastName)
      //compareCollection(obj);

});
但最后我得到了这个:

Orginal Coll 
DeviceId: undefined 
FirstName: undefined 
LastName: undefined

问题是什么?

我可以看到此命令存在一些问题:

db.location.aggregate([
 {$match : { FirstName: { $nin : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])
$match阶段将与问题中提供的文档不匹配,因为您提供的文档具有FirstName:因此该文档将由$in匹配,而不是由$nin匹配 如果$match阶段更改为$in,则它将发出一个文档,分组阶段将有一些工作要做,但分组阶段仅配置为返回_id属性,因此它将返回以下中间文档:

{
"CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"),
"DeviceId" : "89984320001499681816",
"UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"),
"FirstName" : " ",
"LastName" : "",
}
{
    "_id" : "89984320001499681816"
}
$project阶段尝试投影DeviceId,但分组阶段的结果仅包含_id属性,因此无法从该文档投影DeviceId属性

当聚合管道到达forEach函数时,文档中没有DeviceId、FirstName或LastName属性

要进一步了解聚合管道内发生的情况,可以运行以下查询:

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$project: { "DeviceId" : 1, FirstName: 1, LastName: 1 } }
]).forEach(
  function(obj) {
      print(obj);
  }
);
或者,只需单独运行管道中的每个阶段,并检查每个状态的输出,因为它将成为下一阶段的输入。例如:

这个命令

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } }
])
db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } }
])
db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])
。。。返回:

{
    "_id" : ObjectId("59d13b64c26584cd8b7a15c8"),
    "CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"),
    "DeviceId" : "89984320001499681816",
    "UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"),
    "FirstName" : " ",
    "LastName" : ""
}
{
    "_id" : "89984320001499681816"
}
{
    "_id" : "89984320001499681816"
}
这个命令

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } }
])
db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } }
])
db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])
。。。返回:

{
    "_id" : ObjectId("59d13b64c26584cd8b7a15c8"),
    "CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"),
    "DeviceId" : "89984320001499681816",
    "UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"),
    "FirstName" : " ",
    "LastName" : ""
}
{
    "_id" : "89984320001499681816"
}
{
    "_id" : "89984320001499681816"
}
这个命令

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } }
])
db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } }
])
db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])
。。。返回:

{
    "_id" : ObjectId("59d13b64c26584cd8b7a15c8"),
    "CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"),
    "DeviceId" : "89984320001499681816",
    "UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"),
    "FirstName" : " ",
    "LastName" : ""
}
{
    "_id" : "89984320001499681816"
}
{
    "_id" : "89984320001499681816"
}

这应该清楚地表明,一旦在$group阶段中添加,您将丢失DeviceId、FirstName和LastName属性,因此您无法在forEach函数中打印这些属性

谢谢你,伙计。但假设我有两个相同设备Id的文档,但其中一个FirstName字段为空‍分组‍ 首先过滤文档,然后根据某种条件过滤并将名已填充的文档发送给方法。你的idia是什么?@sayres抱歉我听不懂你最后的评论。我认为上面的答案准确地解释了为什么您的forEach函数获取的文档没有您期望的状态。答案还提供了一些关于如何自己诊断这些问题的提示。如果你仍然有问题,也许你可以提出另一个问题,或者至少更新你的原始问题,以清楚地说明你的投入、你期望的最终结果以及你迄今为止所做的尝试?老兄,你的解释很清楚,我理解发生了什么。非常感谢。