JAVA实现&原生命令-删除MongoDB列表某项/数组某项

本文目的:删除MongoDB列表某项/数组某项

关键命令一: $pull、update.pull

The $pull operator removes from an existing array all instances of a value or values that match a specified condition.
它用于删除数组所匹配的项,如果数组[1,1,2,1] 执行pull 1 后,只剩下[2]

关键命令二: $upset、update.upset

($unset运算符删除特定字段。请考虑以下语法:)
The $unset operator deletes a particular field. Consider the following syntax: copycopied
{ $unset: { <“field1”>: “”, … } }

下面看具体例子----||
.

例一. 删除简单数组元素

/* 1 */
{
    "_id" : ObjectId("5ec8c716a0d7734e6c2f16fa"),
    "name" : "数据1",
    "datas" : [ 
        "AA", 
        "BB", 
        "CC"
    ],
}
/* 2 */
{
    "_id" : ObjectId("5ec8c74ca0d7734e6c2f16fb"),
    "name" : "数据2",
    "datas" : [ 
        "AA", 
        "DD", 
        "EE"
    ],
}

在这里插入图片描述

需求一:删除name为数据1的datas数组里面的AA

安排!
执行以下命令

db.getCollection('dateList').updateMany({'name':'数据1'},{'$pull': {'datas':'AA'}})

执行后结果是:数据1的datas的AA已删除

/* 1 */
{
    "_id" : ObjectId("5ec8c716a0d7734e6c2f16fa"),
    "name" : "数据1",
    "datas" : [ 
        "BB", 
        "CC"
    ],
}

/* 2 */
{
    "_id" : ObjectId("5ec8c74ca0d7734e6c2f16fb"),
    "name" : "数据2",
    "datas" : [ 
        "AA", 
        "DD", 
        "EE"
    ],
}

在这里插入图片描述

需求二:删除所有数据数组datas里面的AA

执行以下命令

db.getCollection('dateList').updateMany({'datas':'AA'},{'$pull': {'datas':'AA'}})

执行后结果是:数组datas里面的AA都已删除

/* 1 */
{
    "_id" : ObjectId("5ec8c716a0d7734e6c2f16fa"),
    "name" : "数据1",
    "datas" : [ 
        "BB", 
        "CC"
    ],
}

/* 2 */
{
    "_id" : ObjectId("5ec8c74ca0d7734e6c2f16fb"),
    "name" : "数据2",
    "datas" : [ 
        "DD", 
        "EE"
    ],
}

在这里插入图片描述

需求三:JAVA实现

/**
 * 实体类
 */
public class DateList {
   private String id;
   private String name;
   private List<String> datas;
}

/**
 * 删除数组内部项,接口
 * @param data 删除项的值
 * @return
 */
@RequestMapping(value = "delete/{data}")
@ResponseBody
public Object delete(@PathVariable("data") String data){
//  Query query = new Query(Criteria.where("name").is("数据1")); //查询条件:上面需求一形式
    Query query = new Query(Criteria.where("datas").is(data));  //查询条件:上面需求二形式
    Update update = new Update();//更新设置
    update.pull("datas", data);
    mongoTemplate.updateMulti(query, update, DateList.class);
    return null;
}

.

例二. 删除文档数组元素

{
    "_id" : ObjectId("5ec8f2b4a0d77352bc90c929"),
    "name" : "数据1",
    "datas" : [ 
        {
            "time" : "9999",
            "counts" : NumberLong(30)
        }, 
        {
            "time" : "10000",
            "counts" : NumberLong(88)
        }
    ],
}

在这里插入图片描述

需求一:删除time="9999"的datas项

命令

db.getCollection('dateList').updateMany({},{$pull:{datas:{time:"9999"}}})
或者
db.getCollection('dateList').updateMany({'datas.time':"9999"},{$pull:{datas:{time:"9999"}}})

执行后结果:

{
    "_id" : ObjectId("5ec8f2b4a0d77352bc90c929"),
    "name" : "数据1",
    "datas" : [ 
        {
            "time" : "10000",
            "counts" : NumberLong(88)
        }
    ],
}

在这里插入图片描述

需求二:JAVA实现

/**
 * 实体类
 */
public class DateList {
   private String id;
   private String name;
   private List<TimeCount> datas;
}

public class TimeCount {
    private String time;
    private Long counts;
}

/**
 * 删除数组内部项
 * @param data
 * @return
 * @throws Exception
 */
@RequestMapping(value = "delete/{data}")
@ResponseBody
public Object delete(@PathVariable("data") String data) throws Exception {

    Query query = new Query(Criteria.where("datas.time").is(data));
    Update update = new Update();

    Document doc = new Document();
    doc.put("time",data);
    update.pull("datas",doc);

    mongoTemplate.updateMulti(query, update, DateList.class);
    return null;
}

我们对比一下,后面这个跟前面不一样的是:
在这里插入图片描述
可以dubug看一下,这样操作之后的query和update的值
在这里插入图片描述
可以看出,这样是跟mongo的执行命令一致了,所以说不管是什么语言封装,调用驱动的时候都是用相同的命令
.

例三. 删除多层嵌套数组某个文档

例二的升级版,先看看数据格式,数组 datas 里面有数组 counts ,现在删除的是counts 的数据

{
    "_id" : ObjectId("5ecde35f3bf8aad5abfe111d"),
    "name" : "数据1",
    "datas" : [ 
        {
            "time" : "9999",
            "counts" : [ 
                {
                    "man" : "张山",
                    "girl" : "小丽"
                }, 
                {
                    "man" : "李四",
                    "girl" : "小红"
                }
            ]
        }, 
        {
            "time" : "10000",
            "counts" : [ 
                {
                    "man" : "王五",
                    "girl" : "小花"
                }
            ]
        }
    ]
}

在这里插入图片描述

需求:删除张山这个文档

先上命令

db.dateList.updateMany({'datas.time':"9999"},{$pull:{'datas.$.counts':{'man':"张山"}}})

结果:

{
    "_id" : ObjectId("5ecde35f3bf8aad5abfe111d"),
    "name" : "数据1",
    "datas" : [ 
        {
            "time" : "9999",
            "counts" : [ 
                {
                    "man" : "李四",
                    "girl" : "小红"
                }
            ]
        }, 
        {
            "time" : "10000",
            "counts" : [ 
                {
                    "man" : "王五",
                    "girl" : "小花"
                }
            ]
        }
    ]
}

.

例四. 删除数组里面某个集合的键值

在这里插入图片描述

需求一:删除datas里面time="9999"的time这个键值

直接上命令命令

db.dateList.updateMany({'datas.time':"9999"},{$unset:{'datas.$.time':null}})
或
db.dateList.updateMany({'datas.time':"9999"},{$unset:{'datas.$.time':""}})

这里不用 pull 命令,改用upset

用upset来删除指定键值,这刚好满足这个需求

执行结果(源数据跟例二一样)

{
    "_id" : ObjectId("5ecd0d2ba0d773837421459a"),
    "name" : "数据1",
    "datas" : [ 
        {
            "counts" : NumberLong(30)
        }, 
        {
            "time" : "10000",
            "counts" : NumberLong(88)
        }
    ],
}

在这里插入图片描述

需求二:JAVA实现(实体类跟例二一样)

@RequestMapping(value = "delete/{data}")
@ResponseBody
public Object delete(@PathVariable("data") String data) throws Exception {
    Query query = new Query(Criteria.where("datas.time").is(data));
    Update update = new Update();
    update.unset("datas.$.time");
    mongoTemplate.updateMulti(query, update, DateList.class);
    return null;
}

最后,总结

本文从删除数组内部的项出发解决几个场景问题
本质是删除文档内嵌数据

不同的是pull是删除内嵌数组项,upset是删除内嵌键值

刚好例四是删除数组里面的键值,将两者完美结合,实际上upset可以删除文档内部任意键值
另外还有个知识点,"$" 字符

在例四中,"$" 字符 代表 下标位置索引, 满足条件的数据下标位置就会传递给 这个 字符。使用的场景就是当操作的对象是数组里面某个符合的项,然后对这些项进行内部操作。
比如

db.dateList.updateMany({'datas.time':"9999"},{$unset:{'datas.$.time':""}})

就是操作 datas数组里面符合条件的项,如下图
在这里插入图片描述
正常情况下,需要这样去改变

$unset:{'datas.0.time':""}

也就是说要指定下标,但是当使用场景下标不明确的时候,就需要用$去占位。

完结。

感谢
https://blog.csdn.net/wonder_dog/article/details/82682099

https://docs.mongodb.com/v3.2/reference/operator/update/unset/
https://www.cnblogs.com/yanzhi-1996/articles/11095002.html
https://blog.csdn.net/weixin_30950237/article/details/99468786

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cy谭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值