首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MapReduce用于确定分类帐中的贷方余额

MapReduce用于确定分类帐中的贷方余额
EN

Stack Overflow用户
提问于 2015-05-09 19:28:05
回答 2查看 520关注 0票数 1

我有一个交易分类账,其中的借方和信用交易是存储。我需要确定account : 121的信用余额。我找到了办法。只是,我不明白我所做的事情的一半,以及为什么这样做是可行的。

代码语言:javascript
复制
var dummyschema = mongoose.Schema({
  account: Number,
  refAccount: Number,
  credit: Boolean,
  amount: Number,

});

var dummyTx = mongoose.model('dummyTx', dummyschema);

var c = {};
c.map = function() {emit("credit", this.amount);};
c.reduce = function(key, values) { return Array.sum(values);};
c.query = { account : 121, credit: true };
c.out = {inline:1};

var d = {};
d.map = function() {emit("debit", this.amount);};
d.reduce = function(key, values) { return Array.sum(values);};
d.query = { account : 121, credit: false };
d.out = {inline:1};

dummyTx.mapReduce(c, function (error, credit) {
  dummyTx.mapReduce(d, function (err, debit) {
    console.log(credit['0'].value - debit['0'].value);
  });
});

你能告诉我有什么更好的方法吗?我读过MapReduce文档条目,但它大多在我头上飞过。如果你给我密码,我会试着理解它..。虽然一个解释会更有帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-09 20:23:19

您可以采取的一种方法是使用聚合框架。实现所需结果的聚合管道是一个$match操作符,它根据给定的查询条件过滤集合中的文档,在您的情况下,它将是帐号为121个的文档。

再往下走就是魔法发生的地方。$project操作符通过添加一个额外的字段来重塑文档,余额将用于计算该帐户的总数。balance字段将使用$cond$multiply运算符来获得它的值,条件是如果信用值为false,那么它将从金额乘以-1获得它的值,否则它将是默认的正金额值。

$project管道步骤是$group操作符阶段之后,当文档按帐户号字段分组时,该阶段将计算总累计余额,这将使用$sum运算符将所有余额值相加。

因此,最终您将得到以下聚合管道:

代码语言:javascript
复制
db.dummyTx.aggregate([
    {
        "$match": { "account": 121 }
    },
    {
        "$project": {
            "balance": {
                 "$cond": [ 
                    {
                        "$eq": [ "$credit", false ]
                    }, 
                    { 
                        "$multiply": [ -1, "$amount" ] 
                    }, 
                    "$amount" 
                 ]
            },
            "account": 1
        }
    },
    {
        "$group": {
            "_id": "$account",
            "total": {
                "$sum": "$balance"
            }
        }
    }
])

让我们通过向dummyTx集合添加一些测试文档来演示这一点:

代码语言:javascript
复制
db.dummyTx.insert([
    { account: 121, credit: true, amount: 5 },
    { account: 121, credit: true, amount: 2 },
    { account: 121, credit: false, amount: 10 },
    { account: 121, credit: false, amount: 2 }
])

上述聚合管道将提供以下结果:

代码语言:javascript
复制
/* 1 */
{
    "result" : [ 
        {
            "_id" : 121,
            "total" : -5
        }
    ],
    "ok" : 1
}

要在猫鼬中实现这一点,您可以使用聚合管道生成器,如下所示:

代码语言:javascript
复制
Model.aggregate()
      .match({"account": 121})
      .project({ "balance": { "$cond": [ 
                    {"$eq": [ "$credit", false ]}, 
                    {"$multiply": [ -1, "$amount" ]}, 
                    "$amount" 
                 ]},
            "account": 1})
      .group({"_id": "$account","total": {"$sum": "$balance"}})
      .exec(callback);

-更新 --

如果您仍然喜欢map选项,您可以尝试下面的地图缩减操作,该操作使用与上面相同的概念;您的映射函数将发出一个键值对,其中包含一个修改后的密钥balance,该条件是:如果信用值为真,则balance字段将有一个正amount,否则将为负值。

然后,约简函数通过将值数组简化为其元素之和来收集和压缩聚集的数据。然后,MongoDB将结果存储在集合outputTx中。因此,Map-还原操作如下所示:

代码语言:javascript
复制
var d = {},
    map = function() {
        var balance = this.credit ? this.amount : -1 * this.amount;
        emit("balance", balance);
    },
    reduce = function(key, values) { return Array.sum(values);};
d.query = { account : 121 };
d.out = "outputTx";

db.dummyTx.mapReduce(map, reduce, d);

查询输出集合db.outputTx.find({})将得到结果:

代码语言:javascript
复制
/* 1 */
{
    "_id" : "balance",
    "value" : -5
}
票数 2
EN

Stack Overflow用户

发布于 2015-05-09 20:22:10

聚合框架是实现所需结果的一种更易读(而且可能更有效)的方法:

我让你把它改编成猫鼬,但从芒果壳上说:

代码语言:javascript
复制
db.dummyTx.aggregate([
    {$match: {account:121}},
    {$project: { credit: {$cond: ["$credit",
                                  "$amount", 
                                  {$subtract: [0, "$amount"]} ]} }},
    {$group: { _id: "$account", balance: {$sum: "$credit"}}}
])
  • $match阶段只保留121号账户;
  • $project阶段将综合一个领域credit,其价值在信用情况下为$amount,在借方情况下为-$amount
  • 最后,$group阶段将(正或负)学分相加,以计算总余额。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30144145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档