首页 > 解决方案 > $divide 嵌入文档的元素 - MongoDB 聚合

问题描述

我正在尝试创建一个聚合 MongoDB 查询。

数据结构:

{
    "object_name": Example,
    "values": [ {"name":"value1", "value":1}, 
                {"name":"value2", "value":10},
                {"name":"total", "value":105}
}

目标:在和和中查找对象名称。以这种方式构造数据以提供关于 value_name 和 value 字段的索引。value1/total > 0.5value2/total > 0.25total > 100

我尝试过的 - 与以下管道聚合:

$match: 过滤总数 > 100 的文档:

$match: { values: { $elemMatch: { value_name: "total", value: {$gte: 100 }

$project: 只获取我们需要的 value_names (有接近 200 个不同的名字)

$project: {
            values: {
                $filter: {
                    input: "$values",
                    as: "value",
                    cond: { $or: [
                        { $eq: [ "$$value.name", "name1"] },
                        { $eq: [ "$$value.name", "name2"] },
                        { $eq: [ "$$value.name", "total"] },
                    ] }
                }
            },
            name: 1
        }

然后,{ $unwind: "$values" }

在这里,我可以$group$divide: name1/total, name2/total但是我坚持如何获得这些价值观。我不能简单地这样做stats.value:,因为它不知道我指的是哪个值。我相信$group不能做$elemMatch也匹配的名字。

如果有更简单的解决方案,我将非常感谢您的意见。

标签: mongodbaggregation

解决方案


您可以使用$arrayToObject运算符将数组转换为对象并添加tmp字段以轻松访问value1, value2,total

db.collection.aggregate([
  {
    $addFields: {
      tmp: {
        $arrayToObject: {
          $map: {
            input: "$values",
            as: "value",
            in: {
              k: "$$value.name",
              v: "$$value.value"
            }
          }
        }
      },
      name: 1
    }
  },
  {
    $match: {
      $expr: {
        $and: [
          {
            $gt: [
              {
                $divide: [
                  "$tmp.value1",
                  "$tmp.total"
                ]
              },
              0.5
            ]
          },
          {
            $gt: [
              {
                $divide: [
                  "$tmp.value2",
                  "$tmp.total"
                ]
              },
              0.25
            ]
          },
          {
            $gt: [
              "$tmp.total",
              100
            ]
          }
        ]
      }
    }
  },
  {
    $project: {
      tmp: 0
    }
  }
])

Mongo游乐场


推荐阅读