【问题标题】:mongodb aggregation $in with $typemongodb 聚合 $in 和 $type
【发布时间】:2020-04-25 07:53:14
【问题描述】:

我有一个收藏:

{
  values: [null, null, 1, 2, 3, 4.6],
}

我想收到一个属性,它告诉我这些值是否是数字。

我试过了:

{
    $project: {
        hasNumber: {
            $in: [{ $eq: [{ $type: '$$CURRENT' }, 'number'] }, '$values'],
        },
    },
}

但它不起作用,聚合可以实现这样的事情吗?

【问题讨论】:

    标签: mongodb aggregate


    【解决方案1】:

    正在调试您的代码...

    $in: [{ $eq: [{ $type: '$$CURRENT' }, 'number'] }, '$values'],
    

    您正在检查false 是否在$values 内。

    说明:

    • '$$CURRENT' 返回原始文档
    • { $type: '$$CURRENT' } 返回'object'
    • $eq:['object', 'number'] 将始终返回 false
    • $in:[ 'false', '$values'] 将是错误的

    我已经用$convert 运算符解决了

    db.collection.aggregate([
      {
        $project: {
          hasNumber: {
            $cond: [
              {
                $eq: [
                  {
                    $map: {
                      input: "$values",
                      in: {
                        $convert: {
                          input: "$$this",
                          to: "int",
                          onError: -999,
                          onNull: -999
                        }
                      }
                    }
                  },
                  "$values"
                ]
              },
              true,
              false
            ]
          }
        }
      }
    ])    
    

    【讨论】:

    • 我明白了,'$$CURRENT' 返回原始文档...那么,有没有办法将迭代器与 $in 运算符一起使用?
    【解决方案2】:

    请试试这个:

    db.yourCollectionName.aggregate([{
        $project: {
            values: 1, hasNumber: {
                $gt: [{
                    $size: {
                        $filter:
                        {
                            input: "$values",
                            as: "value",
                            cond: { $eq: [{ $type: '$$value' }, 'int'] }
                            // To check & include double as well, replace above cond with this :
                           //cond: { $or :[ {$eq: [{ $type: '$$value' }, 'int']} , {$eq: [{ $type: '$$value' }, 'double']}] }
                        }
                    }
                }, 0]
            }
        }
    }])
    

    收集数据:

    /* 1 */
    {
        "_id" : ObjectId("5e14d9dd627ef78236ea77e3"),
        "values" : [ 
            null, 
            null, 
            1, 
            2, 
            3, 
            4.6
        ]
    }
    
    /* 2 */
    {
        "_id" : ObjectId("5e14d9e4627ef78236ea785f"),
        "values" : [ 
            null, 
            null
        ]
    }
    
    /* 3 */
    {
        "_id" : ObjectId("5e14decc627ef78236eb12d3"),
        "values" : [ 
            "1", 
            4.6
        ]
    }
    

    结果:

    /* 1 */
    {
        "_id" : ObjectId("5e14d9dd627ef78236ea77e3"),
            "values" : [
                null,
                null,
                1,
                2,
                3,
                4.6
            ],
                "hasNumber" : true
    }
    
    /* 2 */
    {
        "_id" : ObjectId("5e14d9e4627ef78236ea785f"),
            "values" : [
                null,
                null
            ],
                "hasNumber" : false
    }
    /* 3 */ // If we're checking for double this hasNumber will be true
    {
        "_id" : ObjectId("5e14decc627ef78236eb12d3"),
            "values" : [
                "1",
                4.6
            ],
                "hasNumber" : false
    }
    

    【讨论】:

    • 它是否也适用于double,是否可以使用number 而不是int 来完成?
    • 这可以通过 $in 运算符实现吗?
    • @DanielPérez : $in 运算符主要用于检查项目列表 - Ex:-[1,2,3] 存在于现有文档 Ex :- values array [null,null,1,2,3,4.6] 的数组字段中,但通常输入到 $in 将是来自代码,但在聚合管道中使用 $in 似乎不太可行,您是否要传递值列表并检查 values 数组中是否存在任何传递的输入值类型?
    • 我想要一些类似于 javascript array.find(el => typeof el === 'number') 方法的东西。我认为 $in 是最接近的,但它似乎更像 .includes
    • @DanielPérez : 是的 .includes/.filter 但不是 .find.some :-) 据我所知 mongo 没有直接类似于 .find() 的东西在数组上,所以即使在这里我们也在对过滤器进行大小检查..
    猜你喜欢
    • 2019-02-25
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多