MongoDB子文档投影

MongoDB子文档投影,mongodb,Mongodb,需要一些关于基于子文档属性值的Mongo查询的帮助,但也需要禁止该子文档属性出现在结果中 以下是我的用户对象: { "username" : "abc", "emails" : [ { "address" : "abc1@email.com", "default" : true }, { "address" : "abc2@email.com", "default" : false } ] }, {

需要一些关于基于子文档属性值的Mongo查询的帮助,但也需要禁止该子文档属性出现在结果中

以下是我的用户对象:

{
  "username" : "abc",
  "emails" : [
    {
      "address" : "abc1@email.com",
      "default" : true
    },
    {
      "address" : "abc2@email.com",
      "default" : false
    }
  ]
},
{
  "username" : "xyz",
  "emails" : [
    {
      "address" : "xyz1@email.com",
      "default" : false
    },
    {
      "address" : "xyz2@email.com",
      "default" : true
    }
  ]
}
我的目标是通过电子邮件获得以下输出。默认值:true,但结果中不显示emails.default属性:

{
  "username" : "abc",
  "emails" : [
    {
      "address" : "abc1@email.com",
    }
  ]
},
{
  "username" : "xyz",
  "emails" : [
    {
      "address" : "xyz2@email.com",
    }
  ]
}
使用$positional操作符:

collection.find({"emails.default":true}, {"username":1,"emails.$":1})
我获得了要显示的正确电子邮件子文档,但仍然返回了emails.default属性:

{
  "username" : "abc",
  "emails" : [
    {
      "address" : "abc1@email.com",
      "default" : true
    }
  ]
},
{
  "username" : "xyz",
  "emails" : [
    {
      "address" : "xyz2@email.com",
      "default" : true
    }
  ]
}
出于某种原因,当我使用这句话时:

collection.find({"emails.default":true}, {"username":1,"emails.address":1})
我得到以下结果,好像语句的查询部分被忽略了一样

{
  "username" : "abc",
  "emails" : [
    {
      "address" : "abc1@email.com",
    },
    {
      "address" : "abc2@email.com",
    }
  ]
},
{
  "username" : "xyz",
  "emails" : [
    {
      "address" : "xyz1@email.com",
    },
    {
      "address" : "xyz2@email.com",
    }
  ]
}

非常感谢您的帮助,提前感谢。

我认为这不是受支持的功能。您要求在数组的文档中投影选定字段。看到这个了吗


但我认为您的文档结构将存储大量冗余数据。只有一个默认的电子邮件地址。将其作为父文档的一部分。更新/预测将更加简单。您的阵列电子邮件现在实际上只存储电子邮件。

我认为这不是受支持的功能。您要求在数组的文档中投影选定字段。看到这个了吗


但我认为您的文档结构将存储大量冗余数据。只有一个默认的电子邮件地址。将其作为父文档的一部分。更新/预测将更加简单。您的数组电子邮件现在实际上只存储电子邮件。

对于MongoDB 2.6中的位置运算符,您不能有选择地排除匹配的数组元素的字段

但是,您可以使用MongoDB 2.2+中的聚合框架来实现您想要的结果:

db.user.aggregate(

    // Match on relevant documents to optimize query
    { $match: {
        username: "abc"
    }},

    // Convert the "emails" address into a stream of documents
    { $unwind: "$emails" },

    // Only include the emails with default:true
    { $match: {
        "emails.default" : true
    }},

    // Project the desired fields
    { $project: {
        _id : 0,
        username: 1,
        "emails.address": 1
    }}
)
样本结果:

{
    "username" : "abc",
    "emails" : {
        "address" : "abc1@email.com"
    }
}

使用MongoDB 2.6中的位置运算符,您不能有选择地排除匹配的数组元素的字段

但是,您可以使用MongoDB 2.2+中的聚合框架来实现您想要的结果:

db.user.aggregate(

    // Match on relevant documents to optimize query
    { $match: {
        username: "abc"
    }},

    // Convert the "emails" address into a stream of documents
    { $unwind: "$emails" },

    // Only include the emails with default:true
    { $match: {
        "emails.default" : true
    }},

    // Project the desired fields
    { $project: {
        _id : 0,
        username: 1,
        "emails.address": 1
    }}
)
样本结果:

{
    "username" : "abc",
    "emails" : {
        "address" : "abc1@email.com"
    }
}