首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mongomock中的聚合内部的$sum似乎不起作用。

mongomock中的聚合内部的$sum似乎不起作用。
EN

Stack Overflow用户
提问于 2018-11-20 19:36:08
回答 1查看 665关注 0票数 2

我有一个聚合的Mongo查询,它投影一些字段,并使用$sum计算另外两个字段。查询工作正常,所以我为它创建了一个单元测试,让我感到惊讶的是,测试失败了。

我创建了一个最小、完整和可验证的示例来验证我的假设,即这是MongoMock的一个问题,而且它似乎是!

以下是代码:

代码语言:javascript
复制
import mongoengine as mongo
from mongoengine import connect
from mongoengine.queryset import QuerySet

class ValuesList(mongo.EmbeddedDocument):
    updated_value = mongo.DecimalField()


class ValuesHistory(mongo.Document):
    name = mongo.StringField()
    base_value = mongo.DecimalField()
    values_list = mongo.EmbeddedDocumentListField(ValuesList, required=False)
    meta = {
        'collection' : 'values_history'
    }

    def __str__(self):
        return 'name: {}\nbase_value: {}\n'.format(self.name, self.base_value)


def migrate_data(new_collection):
    ValuesHistory.objects.aggregate(
        {'$project': {'name': 1,
                     'base_value': {'$sum': ['$base_value', {'$arrayElemAt': ['$values_list.updated_value', -1]}]}
                      }
        },
        {'$out': "{}".format(new_collection)}
    )


def clear_tables_and_insert_test_data(db):
    db.test.values_history.drop()
    db.test.updated_values.drop()
    ValuesHistory(name='first',
                  base_value=100,
                  values_list=[ValuesList(updated_value=5),
                               ValuesList(updated_value=15)]).save()

def run_aggregate_query_with_db(db):
    new_collection_name = 'updated_values'

    migrate_data(new_collection_name)

    new_group = ValuesHistory.switch_collection(ValuesHistory(), new_collection_name)
    aggregated_values = QuerySet(ValuesHistory, new_group._get_collection()).all()
    for value in aggregated_values:
        print(value)

    db.close()

对上述代码的快速解释。

ValuesHistory是一个包含字符串名称、数值base_value和值列表(ValuesList类)的类。

clear_tables_and_insert_test_data方法清除此测试中使用的两个表,并插入一些测试数据。

migrate_data方法中的查询创建一个新集合(通过$out操作符),新创建的集合的base_value应该是当前值和values_list列表中最后一个值的总和。在我的例子中,应该是115 ( 100是当前值,15是列表中的最后一个值)。

如果我使用到本地MongoDB的连接运行代码,如下所示:

代码语言:javascript
复制
if __name__ == '__main__':
    db = connect('test') # connect to real instance of Mongo
    clear_tables_and_insert_test_data(db)
    run_aggregate_query_with_db(db)

结果我得到了115,这正是我们所期望的。

如果我使用到MongoMock的连接:

代码语言:javascript
复制
if __name__ == '__main__':
    db = connect('test', host='mongomock://localhost') # Connect to MongoMock instance
    clear_tables_and_insert_test_data(db)
    run_aggregate_query_with_db(db)

我得到的结果是100,这是奇怪的!看起来$sum操作符没有正确地完成它的工作,因为100和15的总和导致了100!

编辑:我也尝试使用$add操作符,但问题仍然是一样的,当它应该是115时产生100。

TL;DR;

问题:我应该如何在MongoMock上的聚合管道中使用$sum (或$add),以使其产生正确的值?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-22 12:25:09

实际上,所描述的问题是一直存在到3.14.0版本的Mongomock上的一个bug。

在最初的问题发布后,我在Mongomock的github上打开了描述这个问题的问题。在它被修复后不久,版本3.15.0在几天前就发布了。我运行了关于这个问题的代码,现在$add和$sum操作符都解决了这个问题!

TL;博士

更新到Mongomock 3.15.0就足以解决这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53400319

复制
相关文章

相似问题

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