如果列表中包含值,则将其分组为新类别

时间:2017-10-12 20:41:58

标签: mongodb mongodb-query aggregation-framework

尝试构建一个聚合查询,允许我对zipcodes进行分类并返回每个组的计数。

该文件部分看起来像

{ 
"_id" : ObjectId("value"), 
"updatedAt" : ISODate("value"), 
"zip" : "11209", 
"state" : "NY", 
"city" : "New York", 
}

我想通过将“zip”字段与具有n个互斥值的数组进行比较来分组

east_ny_zipcodes = [11209, 11210, 11211, ...]
lower_ny_zipcodes = [11212, 11213, 11214, ...]

理想情况下返回类似

的内容
{
lower_ny: 1200, 
upper_ny: 1500,
east_ny: 2000
}

1 个答案:

答案 0 :(得分:1)

使用3.4以后的MongoDB,您可以使用$in来比较数组:

(x, y) => "bla"

如果你没有,那么自MongoDB 2.6以来就有$setIsSubset。语法和意图略有不同。但是你的名单是“独一无二的”,所以这不是问题:

db.zips.aggregate([
  { "$group": {
    "_id": null,
    "lower_ny": {
      "$sum": {
        "$cond": [{ "$in": [ "$zip", lower_ny_zipcodes ] },1,0]
      }
    },
    "east_ny": {
      "$sum": {
        "$cond": [{ "$in": [ "$zip", east_ny_zipcodes ] },1,0]
      }
    },
    "upper_ny": {
      "$sum": {
        "$cond": [{ "$in": [ "$zip", upper_ny_zipcodes ] },1,0]
      }
    }
  }}
])

本质上它只是与外部定义的数组内容的逻辑比较,后者在作为操作发送的BSON内容中得到扩展。

当然,数组中的值也必须是“字符串”才能匹配。但如果您还没有这样做,那就很容易了:

db.zips.aggregate([
  { "$group": {
    "_id": null,
    "lower_ny": {
      "$sum": {
        "$cond": [{ "$setIsSubset": [ ["$zip"], lower_ny_zipcodes ] },1,0]
      }
    },
    "east_ny": {
      "$sum": {
        "$cond": [{ "$setIsSubset": [ ["$zip"], east_ny_zipcodes ] },1,0]
      }
    },
    "upper_ny": {
      "$sum": {
        "$cond": [{ "$setIsSubset": [ ["$zip"], upper_ny_zipcodes ] },1,0]
      }
    }
  }}
])