代码之家  ›  专栏  ›  技术社区  ›  BeetleJuice

Mongo:添加字段,计算另一个字段出现的次数

  •  0
  • BeetleJuice  · 技术社区  · 6 年前

    我是MongoDB的新手。我正在写一个应用程序使用猫鼬和NodeJS。我从这个系列开始:

    [
      { name: "Joe", hobby: "Food"},
      { name: "Lyn", hobby: "Food"},
      { name: "Rex", hobby: "Play"},
      { name: "Rex", hobby: "Shop"},
      ...
    ]
    

    nameCount hobbyCount 为文档的爱好显示相同的内容:

    [
      { name: "Joe", hobby: "Food", nameCount: 1, hobbyCount: 2 },
      { name: "Lyn", hobby: "Food", nameCount: 1, hobbyCount: 2 },
      { name: "Rex", hobby: "Play", nameCount: 2, hobbyCount: 1 },
      { name: "Rex", hobby: "Shop", nameCount: 2, hobbyCount: 1 }
    ]
    

    通过我的研究和摆弄,我得到了下面的查询工作,但它似乎过高,低效和过于复杂。

    db.members.aggregate([
      {$skip: 0},
      {$limit: 4},
      {
        $lookup: {
          from: "members",
          let: { name: "$name"},
          pipeline: [
            { $match: { $expr: { $eq: ["$name", "$$name"] } } },
            { $count: "count" }
          ],
          as: "nameCount"
        }
      },
      { $unwind: "$nameCount" },
      { $addFields: { nameCount: "$nameCount.count" } },
      {
        $lookup: {
          from: "members",
          let: { hobby: "$hobby"},
          pipeline: [
            { $match: { $expr: { $eq: ["$hobby", "$$hobby"] } } },
            { $count: "count" }
          ],
          as: "hobbyCount"
        }
      },
      { $unwind: "$hobbyCount" },
      { $addFields: { hobbyCount: "$hobbyCount.count" } }
    ]);
    

    Mongo Playground

    姓名计数 霍比计数

    See the playground

    0 回复  |  直到 5 年前
        1
  •  1
  •   Valijon    6 年前

    编辑: $lookup (我们通过名字和爱好来匹配)和计数 nameCount hobbyCount 通过应用 $filter $reduce 操作员

    db.members.aggregate([
      {
        $skip: 1
      },
      {
        $limit: 2
      },
      {
        $lookup: {
          from: "members",
          let: {
            name: "$name",
            hobby: "$hobby"
          },
          pipeline: [
            {
              $match: {
                $expr: {
                  $or: [
                    {
                      $eq: [
                        "$name",
                        "$$name"
                      ]
                    },
                    {
                      $eq: [
                        "$hobby",
                        "$$hobby"
                      ]
                    }
                  ]
                }
              }
            }
          ],
          as: "count"
        }
      },
      {
        $project: {
          _id: 0,
          name: 1,
          hobby: 1,
          nameCount: {
            $reduce: {
              input: "$count",
              initialValue: 0,
              in: {
                $add: [
                  "$$value",
                  {
                    $cond: [
                      {
                        $eq: [
                          "$name",
                          "$$this.name"
                        ]
                      },
                      1,
                      0
                    ]
                  }
                ]
              }
            }
          },
          hobbyCount: {
            $size: {
              $filter: {
                input: "$count",
                cond: {
                  $eq: [
                    "$hobby",
                    "$$this.hobby"
                  ]
                }
              }
            }
          }
        }
      }
    ])
    

    MongoPlayground