首页 > 解决方案 > MongoDb 4.0.5 问题 - 通过将值从字符串转换为 int 将数组字段项从字符串更新为 int 不起作用

问题描述

我有以下结构的测试集合:

{
    "_id" : ObjectId("5efc8285d573109c093229fe"),   
    "units" : [ 
        {
            "keyword_id" : "44",            
            "rating" : {
                "exact_rating" : {
                    "rating" : "55"
                }
            }
        }, 
        {
            "keyword_id" : "45",
            "rating" : {
                "exact_rating" : {
                    "rating" : "43",
                    "sample-field": "Yes"
                }
            }
        }, 
        {
            "rating" : {
                "exact_rating" : {
                    "rating" : 1,
                    "sample-field": "No"
                }
            }
        }
    ],
    "result_id" : 111,  
};

我需要将string单位数组 ( units.rating.exact_rating.rating) 内部的 rating 字段的值转换为integer并删除对象内部的任何其他字段,例如sample-field. 我正在尝试使用该update()函数forEach()并尝试使用set()以下查询使用该方法,但它不起作用:

db.getCollection('test').find().forEach(function(res)
{    
    print( "Id: " + res._id );
    db.getCollection('test').update(
      { "units.rating.exact_rating" : { $exists: true }},
      { $set: { "units.$[].rating.exact_rating": {"rating": res.units.rating.exact_rating.rating}} },
      { multi: true })
});

标签: mongodb

解决方案


使用 for 循环执行此操作将需要通过网络返回整个集合,在本地对其进行修改,然后通过网络将其发送回以保存。

您可以使用聚合管道在服务器端完成这些任务,并使用 $out 阶段将文档保存在临时集合中。修改完所有内容后,您可以删除原始集合并重命名临时集合以替换它。

db.test.aggregate([
  {$addFields: {
      units: {
        $map: {
          input: "$units",
          as: "unit",
          in: {
            $mergeObjects: [
              "$$unit",
              {rating: {
                  exact_rating: {
                    rating: {
                      $convert: {
                        input: "$$unit.rating.exact_rating.rating",
                        to: "int",
                        onError: {
                          badRating: "$$unit.rating.exact_rating.rating"
                        }
                      }
                    }
                  }
              }}
            ]
          }
        }
      }
  }},
  {$out: "temp_collection"}
])

操场


推荐阅读