Mongo DB - 二级搜索 - elemMatch

时间:2016-09-07 23:50:20

标签: mongodb mongodb-query

我正在尝试获取以下结构的所有记录(以及所有记录的计数)

{
  id: 1,
  level1: {
    level2: 
      [
        {
          field1:value1; 
        },
        {
          field1:value1; 
        },
      ]
  }
},
{
      id: 2,
      level1: {
        level2: 
          [
            {
              field1:null; 
            },
            {
              field1:value1; 
            },
          ]
      }
    }

我的要求是获取已填充field1的记录数(在level2中至少为1)。我需要说取所有id或这些id的数量。

我正在使用的查询是,

db.table.find({}, 
    {
      _id = id,
      value: {
          $elemMatch: {'level1.level2.field1':{$exists: true}}
      }
    }
})

请建议。

EDIT1: 这是我在评论中试图提出的问题。我无法在评论中正确阐明。因此,编辑问题。

{
  id: 1,
  level1: {
    level2: 
      [
        {
          field1:value1; 
        },
        {
          field1:value1; 
        },
      ]
  }
},
{
      id: 2,
      level1: {
        level2: 
          [
            {
              field1:value2; 
            },
            {
              field1:value2; 
            },
            {
              field1:value2; 
            }
          ]
      }
    }
    {
      id: 3,
      level1: {
        level2: 
          [
            {
              field1:value1; 
            },
            {
              field1:value1; 
            },
          ]
      }
    }

我们使用的查询结果为

value1: 4
value2: 3

我想要像

这样的东西
value1: 2 // Once each for documents 1 & 3
value2: 1 // Once for document 2

1 个答案:

答案 0 :(得分:0)

您可以使用以下查找查询执行此操作:

db.table.find({ "level1.level2" : { $elemMatch: { field1 : {$exists: true} } } }, {})

这将返回" level1.level2"中包含field1的所有文档。结构

对于评论中的问题,您可以使用以下聚合来"我必须为field1"中的值返回分组(以及相应的计数):

db.table.aggregate(
  [
    {
      $unwind: "$level1.level2"
    },
    {
      $match: { "level1.level2.field1" : { $exists: true } }
    },
    {
      $group: {
      _id : "$level1.level2.field1",
      count : {$sum : 1}
      }
    }
  ]

更新:对于您的问题"' value1 - 2`在level2,对于文档,假设field1的所有值都相同。"。 我希望我能正确理解你的问题,而不是只对field1的值进行分组,我将文档_id添加为xtra分组:

db.table.aggregate(
  [
    {
      $unwind: "$level1.level2"
    },
    {
      $match: { 
        "level1.level2.field1" : { $exists: true }
      }
    },
    {
      $group: {
            _id : { id : "$_id", field1: "$level1.level2.field1" },
            count : {$sum : 1}
            }
    }
  ]
);

UPDATE2: 我更改了聚合并添加了额外的分组,下面的聚合为您提供了所需的结果。

db.table.aggregate(
  [
    {
      $unwind: "$level1.level2"
    },
    {
      $match: { 
              "level1.level2.field1" : { $exists: true }
            }
    },
    {
      $group: {
                  _id : { id : "$_id", field1: "$level1.level2.field1" }
                  }
    },
    {
      $group: {
                  _id : { id : "$_id.field1"},
                  count : { $sum : 1}
                  }
    }
  ]
);