仅当唯一ID($addtoSet)满足条件时才对其进行计数

wbgh16ku  于 2022-10-22  发布在  Go
关注(0)|答案(1)|浏览(147)

我正在尝试修改这个由元数据库生成的查询。它生成以周为单位的唯一ID计数。我试图实现的是,只有当每个ID在这段时间内至少有X个条目时,才能按周获得唯一ID计数。

[
  {
    "$match": {
      "$and": [
        {
          (some filters)
        },
        {
          "$expr": {
            "$gte": [
              "$createdAt", { "$subtract": [ISODate(), { "$multiply": [3600000, 24, 7, 8] }] }
            ]
          }
        },
        {
          "$expr": {
            "$lt": [
              "$createdAt", ISODate() 
            ]
          }
        }
      ]
    }
  },

  {
    "$group": {
      "_id": {
        "createdAt~~~week": {
          "$let": {
            "vars": {
              "parts": {
                "$dateToParts": {
                  "date": {
                    "$subtract": [
                      "$createdAt",
                      {
                        "$multiply": [
                          {
                            "$subtract": [
                              {
                                "$let": {
                                  "vars": {
                                    "day_of_week": {
                                      "$mod": [
                                        {
                                          "$add": [
                                            {
                                              "$dayOfWeek": "$createdAt"
                                            },
                                            6
                                          ]
                                        },
                                        7
                                      ]
                                    }
                                  },
                                  "in": {
                                    "$cond": {
                                      "if": {
                                        "$eq": [
                                          "$$day_of_week",
                                          0
                                        ]
                                      },
                                      "then": 7,
                                      "else": "$$day_of_week"
                                    }
                                  }
                                }
                              },
                              1
                            ]
                          },
                          86400000
                        ]
                      }
                    ]
                  }
                }
              }
            },
            "in": {
              "$dateFromParts": {
                "year": "$$parts.year",
                "month": "$$parts.month",
                "day": "$$parts.day"
              }
            }
          }
        }
      },
      "count": {
        "$addToSet": "$user._id"
      }
    }
  },
  {
    "$project": {
      "_id": false,
      "createdAt~~~week": "$_id.createdAt~~~week",
      "count": {
        "$size": "$count"
      }
    }
  }
]

主要的问题是这一部分:

"count": {
        "$addToSet": "$user._id"
      }

通过使用“$addtoSet”,它会计算所有唯一的ID,即使是那些只有一个条目的ID。当我正常执行这种类型的查询时,我通常会按ID>Count>Match on Counts进行分组,以满足条件。在这种情况下,由于它是按周分组的,我不知道该如何操作。任何帮助都将不胜感激。

brvekthn

brvekthn1#

您需要添加另一个$group阶段,首先按用户分组,然后对交互进行求和,此时我们可以筛选出所有计数不足的用户并继续管道,如下所示:

db.collection.aggregate([
  {
    $group: {
      _id: {
        user: "$user._id",
        "createdAt~~~week": {
          "$let": {
            "vars": {
              "parts": {
                "$dateToParts": {
                  "date": {
                    "$subtract": [
                      "$createdAt",
                      {
                        "$multiply": [
                          {
                            "$subtract": [
                              {
                                "$let": {
                                  "vars": {
                                    "day_of_week": {
                                      "$mod": [
                                        {
                                          "$add": [
                                            {
                                              "$dayOfWeek": "$createdAt"
                                            },
                                            6
                                          ]
                                        },
                                        7
                                      ]
                                    }
                                  },
                                  "in": {
                                    "$cond": {
                                      "if": {
                                        "$eq": [
                                          "$$day_of_week",
                                          0
                                        ]
                                      },
                                      "then": 7,
                                      "else": "$$day_of_week"
                                    }
                                  }
                                }
                              },
                              1
                            ]
                          },
                          86400000
                        ]
                      }
                    ]
                  }
                }
              }
            },
            "in": {
              "$dateFromParts": {
                "year": "$$parts.year",
                "month": "$$parts.month",
                "day": "$$parts.day"
              }
            }
          }
        }
      },
      sum: {
        $sum: 1
      }
    }
  },
  {
    $match: {
      sum: {
        $gt: x // x is the number of interactions you want the user to have more than, this will only match relevant users.
      }
    }
  },
  {
    "$group": {
      "_id": "$_id.createdAt~~~week",
      "count": {
        "$addToSet": "$_id.user"
      }
    }
  },
  {
    "$project": {
      "_id": false,
      "createdAt~~~week": "$_id",
      "count": {
        "$size": "$count"
      }
    }
  }
])

Mongo Playground
使用这种方法需要注意的一点是,不会出现用户为“0”的星期,如果您希望允许计数为0的文档,则可以使用基于sum字段的条件$addToSet

相关问题