Mongodb从不同的集合中获得两个值并计算百分比

时间:2018-07-23 09:12:00

标签: mongodb mongodb-query aggregation-framework

我在mongodb中有两个集合。

我想尝试计算成功率。如果send.TOTAL/targetAudience小于0.9,我需要将send.TOTAL/targetAudience分开,否则返回0,否则返回1。我在下面共享我的脚本。但是返回错误:$ divide仅支持数字类型,不支持数组和数组

message:

                {
                        "_id" : 1727,
                        "appKey" : "morhipo",
                        "msgMethod" : "CAMPAIGN",
                        "allowApiOverride" : false,
                        "firstChildId" : 0,
                        "secondChildId" : 0,
                        "sampleRate" : 0,
                        "targetAudience" : 1135195
                }



       msgstats:
                {
                        "_id" : ObjectId("5b4ddd02f4eb8c72b57e89bb"),
                        "mid" : 1727,
                        "sent" : {
                                "TOTAL" : 756023,
                                "ANDROID" : 398973,
                                "IOS" : 357050
                        }

            // MY Script
            var condition =0;
            var bol =0;
            db.getMongo().getDBNames().forEach(function(dbName) {
            var instColl=db.getMongo().getDB(dbName).getCollection("message");
            var sending = instColl.aggregate([
              {
                $match: {
                 "endDate" : {$gt:new Date(new Date().setDate(new Date().getDate()-10)),$lte:new Date()},"sendStatus" : "FINISHED","msgMethod" : "CAMPAIGN"
                }
              },
              {
                $lookup: {
                  from: "msgStats",
                  localField: "_id",
                  foreignField: "mid",
                  as: "docs"
                }
              },
              {
                $lookup: {
                  from: "message",
                  localField: "_id",
                  foreignField: "_id",
                  as: "docs1"
                }
              },
              {
                "$project": {
                  "bol":{"$divide":["$docs.sent.TOTAL","$docs1.targetAudience"]},
                  "condition":{"$cond":{if:{$lt:["$bol",0.9]},then: 1, else:0}
                  }
                }
              }
            ]);
            print(condition);
            });

2 个答案:

答案 0 :(得分:0)

您的docs和docs1是一个数组,因此您不能在算术运算中直接访问数组。因此,您需要展开这些数组。

$unwind

db.message.aggregate([
          {
            $lookup: {
              from: "msgstats",
              localField: "_id",
              foreignField: "mid",
              as: "docs"
            }
          },{
            $lookup: {
              from: "message",
              localField: "_id",
              foreignField: "_id",
              as: "docs1"
            }
          },
          {"$unwind" : "$docs"},
          {"$unwind" : "$docs1"},
                        {
            "$project": {
              "bol":{"$divide":["$docs.sent.TOTAL","$docs1.targetAudience"]},
              "condition":{
                  "$cond":{
                      if:{
                          $lt:[{"$divide":["$docs.sent.TOTAL","$docs1.targetAudience"]},0.9]}
                          ,then: 1, 
                          else:0
                      }
              }
            }
          }
        ]);

答案 1 :(得分:0)

$lookup返回输出作为数组。您必须使用$arrayElemAt从数组中提取单个元素。

$project阶段以下使用。 $let表达式读取单个元素,然后在$cond内部进行计算以输出布尔值。

{
  "$project":{
    "condition":{
      "$let":{
        "vars":{
          "total":{"$arrayElemAt":["$docs.sent.TOTAL",0]},
          "targetAudience":{"$arrayElemAt":["$docs1.targetAudience",0]}},
        "in":{
          "$cond":{
            "if":{"$lt":[{"$divide":["$$total","$$targetAudience"]},0.9]},
            "then":1,
            "else":0
          }
        }
      }
    }
  }
}