order表数据有3万多条,goods_info是个数组有1个或多个商品
数据结构:
{
"_id": ObjectId("5c88c1d2363877e6018b****"),
"order_no": "20190313663865191971",
"goods_info": [{
"_id": ObjectId("5c88c1d2363877e6018b****"),
"info": {
"_id": "5bbbe53efc4e4a01000d****",
"LiveSource": "yoox "
}
},
{
"_id": ObjectId("5c88c1d2363877e6018b****"),
"info": {
"_id": "5c6d0d182f47397a058b****",
"LiveSource": " C/MEO COLLECTIVE "
}
}
]
}
查出1条订单的信息
db.order.find({
'order_no':{$in:['20190313663865191971']},
'goods_info':{$elemMatch:{'info.LiveSource':'yoox '}}
})
查找order表所有的有问题数据,大概300多条
var where = {
'goods_info':{$elemMatch:{ 'info.LiveSource':/(^\s+)|(\s+$)/g}}
};
var field = {'order_no':1, 'goods_info':1,'_id':1};
db.getCollection('order').find(where,field)
方法一:脚本(使用正则检查出问题数据,循环数据逐条修改)
适用于goods_info中有多个商品,以下仅供参考
//匹配字符串两侧带空格的数据
var where = {
'goods_info':{$elemMatch:{ 'info.LiveSource':/(^\s+)|(\s+$)/g}}
};
var field = {'order_no':1, 'goods_info':1,'_id':1};
db.getCollection('order').find(where,field).forEach(function(item){
var goods_info = item.goods_info;
goods_info.forEach(function(goods){
if(goods.info.LiveSource) goods.info.LiveSource = goods.info.LiveSource.trim();
});
db.getCollection('order').update({"_id" : item._id},{'$set':{'goods_info':goods_info}},{"multi" : true,"upsert" : false});
});
适用于goods_info中只有1个商品,以下仅供参考
//匹配字符串两侧带空格的数据
var where = {
'goods_info':{$elemMatch:{ 'info.LiveSource':/(^\s+)|(\s+$)/g}}
};
var field = {'order_no':1, 'goods_info':1};
db.getCollection('order').find(where,field).forEach(function(item){
//适用于只有1个商品的,循环goods_info信息,k是下标从0开始,v是值
item.goods_info.forEach(function(v,k){
//删除字符串两侧的空格
var newLiveSource = { $trim: { input: v.info.LiveSource } }; //如果$trim报错用下面的
var newLiveSource = v.info.LiveSource.trim();
//检测删除空格后的数据与原数据是否一致
if(newLiveSource != v.info.LiveSource){
//修改数据
var e_where = {'order_no':item.order_no, 'goods_info._id':v._id};
var e_data = {$set:{'goods_info.0.info.LiveSource':newLiveSource}};
db.getCollection('order').update(e_where, e_data, {"multi" : true,"upsert" : false});
}
});
});
方法二:写一个php方法(使用TP框架,分页循环全部数据检查问题数据,循环数据逐条修改),以下仅供参考
/**
* 脚本:检测order表中直播来源(goods_info.info.LiveSource)数据2端是否有空格,有就删除2端多余的空格
* 思路1:循环所有数据,筛选出有问题的数据ID,逐条修改
* 思路2:循环所有数据,筛选出并所有有问题的数据ID,直接批量修改
* 思路3:使用trim找出问题数据,直接批量修改
* 思路4:使用正则找出问题数据,直接批量修改
*/
public function checkOrderLiveSource(){
//**************查询****************
$total = D('Order')->field('order_no,goods_info')->count();
$page = $_GET['p']?:1;
$page_num = 5000;
$page_total = ceil($total/$page_num);
$index = ($page-1)*$page_num;
$list = [];
$list = D('Order')->field('order_no,goods_info')->limit($index,$page_num)->select();
echo "总共".$page_total."页,当前第".$page."页,下一页<a href='/admin/order/checkOrderLiveSource/p/".($page+1)."'>第".($page+1)."页</a>";echo "<hr/>";
//**************检查****************
$num = 0;
$order_no_arr = [];
foreach($list as $item){
foreach($item['goods_info'] as $k=>$v){
if(isset($v['info']['LiveSource'])){
if(trim($v['info']['LiveSource']) != $v['info']['LiveSource']) {
$order_no_arr[$item['order_no']]['goods_info'] = $item['goods_info'];
var_dump($item['order_no']);echo " - ";
var_dump($v['info']['LiveSource']);
echo "<br/>";
$num++;
}
}
}
}
unset($list);
echo "检查出".$num."条数据,需要处理".count($order_no_arr)."条<br/><hr/>";
//**************处理****************
$obj = new \Think\MongoLink();
$controller = $obj->getCollection('order');
foreach($order_no_arr as $order_no=>$value){
foreach($value['goods_info'] as $key=>$val){
$where = [
'order_no' => $order_no,
'goods_info._id' => $val['_id']
];
$data_ = [
'$set' => [
'goods_info.'.$key.'.info.LiveSource' => trim($val['info']['LiveSource'])
]
];
$res = $controller->update($where, $data_);
var_dump(json_encode($where));echo "<br/>";
var_dump(json_encode($data_));echo "<br/><br/>";
echo "db.order.update({'order_no':'".$order_no."','goods_info._id':'".$val['_id']."'},{\$set:{'goods_info.".$key.".info.LiveSource':'".trim($val['info']['LiveSource'])."'}})";echo "<br/>";
var_dump($order_no);echo " - ";var_dump($res['n']);echo "<br/>";
}
}
}