$在mongodb中的多个字段上设置 [英] $unset on multiple fields in mongodb

查看:412
本文介绍了$在mongodb中的多个字段上设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我在mongoDB中有一个如下所示的集合-

Suppose I have a collection in mongoDB like given below -

{
name : "Abhishek",
Roll_no : null,
hobby : stackoverflow
},
{
name : null,
Roll_no : 1,
hobby : null
}

现在,我想删除文档中字段值为空的字段。我知道我可以按照以下方式使用 $ unset 来做到这一点-

Now I want to delete the fields in my Documents where the field values are null. I know that I can do it using the $unset in following way -

db.collection.updateMany({name: null}, { $unset : { name : 1 }});

对于爱好和姓名字段,我们可以采用相同的方法。

And we could do it in the same way for hobby and name field.

但是我想知道是否可以仅使用一个查询执行相同的删除操作?我想知道是否可以在单个命令中使用 $ or 或其他方式实现相同的效果。

But I was wondering if I can do the same deletion operation using just one query? I was wondering if maybe I could use $or or something else to achieve the same effect but in a single command.

有什么想法吗?

推荐答案

在MongoDB版本上> = 3.2

On MongoDB version >= 3.2 :

您可以利用 .bulkWrite()

let bulkArr = [
  {
    updateMany: {
      filter: { name: null },
      update: { $unset: { name: 1 } }
    }
  },
  {
    updateMany: {
      filter: { Roll_no: null },
      update: { $unset: { Roll_no: 1 } }
    }
  },
  {
    updateMany: {
      filter: { hobby: null },
      update: { $unset: { hobby: 1 } }
    }
  },
];

/** All filter conditions will be executed on all docs
 *  but respective update operation will only be executed if respective filter matches (kind of individual ops) */
db.collection.bulkWrite(bulkArr);

Ref: 批量写入

在MongoDB版本上> = 4.2

On MongoDB version >= 4.2 :

由于要删除多个具有 null 值的字段(其中字段名称不能向下列出或未知),请尝试以下查询:

Since you wanted to delete multiple fields(where field names can't be listed down or unknown) having null value, try below query :

db.collection.update(
  {}, // Try to use a filter if possible
  [
    /** 
     * using project as first stage in aggregation-pipeline
     * Iterate on keys/fields of document & remove fields where their value is 'null'
     */
    {
      $project: {
        doc: {
          $arrayToObject: { $filter: { input: { $objectToArray: "$$ROOT" }, cond: { $ne: ["$$this.v", null] } } }
        }
      }
    },
    /** Replace 'doc' object as root of document */
    {
      $replaceRoot: { newRoot: "$doc" }
    }
  ],
  { multi: true }
);

测试: mongoplayground

Ref: update-with-an-aggregation-pipeline 聚合管道

注意:

我相信这将是一次操作&将来,您可以使用 Joi npm软件包或猫鼬模式验证器来限制将 null 作为字段值写入。如果您可以列出您的字段名称,好像没有太多,再加上数据集的大小太高了,那么请尝试将聚合与 $$ REMOVE 结合使用,如'@thammada'所建议。

I believe this would be one time operation & in future you can use Joi npm package or mongoose schema validators to restrict writing null's as field values. If you can list down your field names as if not too many plus dataset size is way too high then try to use aggregation with $$REMOVE as suggested by '@thammada'.

到目前为止,很多客户端甚至不支持mongo shell的 .updateMany()中的聚合管道版本-当时我使用 .update()解决了他们的问题,如果不起作用,请尝试使用 update + { :true}

As of now, aggregation-pipeline in .updateMany() is not supported by many clients even few mongo shell versions - back then my ticket to them got resolved by using .update(), if it doesn't work then try to use update + { multi : true }.

这篇关于$在mongodb中的多个字段上设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆