代码之家  ›  专栏  ›  技术社区  ›  mike.bronner

如何在MongoDB中使用计算字段进行数学运算?

  •  3
  • mike.bronner  · 技术社区  · 10 年前

    我有一个mongo聚合查询,它使用$project:创建一些计算字段。我发现mongoshell无法使用计算字段进行进一步计算,因为它开始抱怨无法将字符串转换为数字。

    是否有解决方法?查询在不使用计算字段的情况下工作,但它需要我重新计算每一个我想做的数学运算的所有内容,这大大降低了查询速度。

    更新:

    以下查询返回此错误:

    "errmsg" : "exception: $mod only supports numeric types, not String and NumberDouble",
    "code" : 16611,
    "ok" : 0
    

    当然,查询示例在其用例中是没有意义的,但对它执行数学运算的期望是相同的:

    db.books.aggregate([
    {$project:  {
        'priceToInflationRatio': {$multiply: [{'$divide': [{'$subtract': ['$price', 1]}, 5]}, 10]},                                                    
        'priceInflationresult':
            {'$cond': [
                    {'$gt': ['$price', 5]},
                        {'$mod': [
                            'priceToInflationRatio',
                            1]},
                    1
            ]},
    }}
    ])
    

    如果我使用:

                        {'$mod': [
                            '$priceToInflationRatio',
                            1]},
    

    计算结果始终为空。

    更新2-可能的解决方案:

    我可能偶然发现了解决方案:使用两个不同的$project部分。如果我引用了在同一$project部分中创建的字段,它似乎还不知道。因此,我需要在一个部分中创建所有计算字段,然后在另一部分中引用它们。

    以下操作似乎有效:

    db.books.aggregate([
    {$project:  {
        'priceToInflationRatio': {$multiply: [{'$divide': [{'$subtract': ['$price', 1]}, 5]}, 10]}
    }},
    {$project: {
        'priceInflationresult':
            {'$cond': [
                    {'$gt': ['$price', 5]},
                        {'$mod': [
                            '$priceToInflationRatio',
                            1]},
                    1
            ]},
    }}
    ])
    

    这个假设正确吗?这是正确的做法吗?(我很难从SQL学习如何在Mongo中构造查询,所以请耐心等待。)

    1 回复  |  直到 10 年前
        1
  •  3
  •   JohnnyHK    10 年前

    这是可行的,但您可以使用 $let 定义 priceToInflationRatio 作为 $project 因此您可以只使用一个阶段:

    db.books.aggregate([
      {$project: {
        'priceInflationresult': {
          $let: {
            vars: {
              'priceToInflationRatio': {
                $multiply: [{'$divide': [{'$subtract': ['$price', 1]}, 5]}, 10]
              }
            },
            in: {
              '$cond': [
                {'$gt': ['$price', 5]},
                {'$mod': ['$$priceToInflationRatio', 1]},
                1
              ]
            },
          }
        }
      }}
    ])