`
mj4d
  • 浏览: 299847 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java操作mongodb(二)之修改、删除及其他

阅读更多

上文,主要整理了java操作mongodb的一些基本概念以及新增、查询等操作,本文对修改、删除等做一些总结

1、修改、删除

删除操作

//根据指定条件删除,与下面方法一致,调用默认WriteConcern.NORMAL:网络错误时抛出异常
collection.remove(new BasicDBObject("name", "robin"));
//根据指定条件删除,指定写入模式
collection.remove(new BasicDBObject("username", "robin"), WriteConcern.NORMAL);

更新提供了一个多态的方法供使用:

/**
*q         根据条件查询需要更新的记录
*o         更新集合
*upsert 如果没有记录q是否插入
*multi    是否更新多条
*/
public abstract WriteResult update( DBObject q , DBObject o , boolean upsert , boolean multi , WriteConcern concern, DBEncoder encoder );

 如:

//根据age=32更新,注意更新后该文档只有username=jack,同时多条只会更新一条,不存在不会插入
WriteResult cursor = collection.update(new BasicDBObject("age", 32), new BasicDBObject("username", "jack"));
//根据age来更新,会追加熟悉gengder=male
collection.update(new BasicDBObject("age", 33), new BasicDBObject("$set", new BasicDBObject("gender", "male")));

//根据username来更新,修改age如果没有追加,更新所有满足条件的文档
collection.update(new BasicDBObject("username", "jack"),
        new BasicDBObject("$set", new BasicDBObject("age", 32)), false, true);

//根据username更新,且age+10
collection.updateMulti(new BasicDBObject("username", "jack"), new BasicDBObject("$inc", new BasicDBObject(
        "age", 10)));

以上各个方法都返回WriteResult,需要返回更多信息可以通过WriteConcern来设置。同时还提供了其他接口来获取更新的数据(包括更新前或更新后的数据)

 /**
     * Finds the first document in the query and updates it.
     * @param query query to match
     * @param fields fields to be returned
     * @param sort sort to apply before picking first document
     * @param remove if true, document found will be removed
     * @param update update to apply
     * @param returnNew if true, the updated document is returned, otherwise the old document is returned (or it would be lost forever)
     * @param upsert do upsert (insert if document not present)
     * @return the document
     * @throws MongoException
     */
    public DBObject findAndModify(DBObject query, DBObject fields, DBObject sort, boolean remove, DBObject update, boolean returnNew, boolean upsert) 

 

 

2、数据库、索引

2.1数据库

mongodb中的数据库对应文档,在前面已经介绍可以通过

DB db = mongo.getDB("sample");

来实例一个数据库对象,如果当然Mongo实例没有该数据库会默认创建一个。此外还提供了一些方法操作数据库:

//获取当前mongo实例创建后所有数据库,可能包括在客户端创建而服务端不存在的数据库(数据库开始在客户端不存在)
public Collection<DB> getUsedDatabases();

//返回服务端所有数据库名字
public List<String> getDatabaseNames();

//删除指定数据库
public void dropDatabase(String dbName);

当然对于数据库,删除也可以通过DB对象方法:

//删除数据库
DB db = mongo.getDB("sample");
db.dropDatabase();
db.command(new BasicDBObject("dropDatabase", 1));

 

2.2索引

在mongo中,我们可以通过以下命令来建立索引:

//对username建立索引
db.smaple.ensureIndex({"username":1})
//对username建立正向索引,age简历反向索引
db.smaple.ensureIndex({"username":1, "age":-1})
//唯一索引
db.smaple.ensureIndex({"username":1},{"unique":true})
//消除重复索引
db.smaple.ensureIndex({"username":1},{"unique":true,"dropDups":true})

在java中也可以通过以下api来做同样的事情:

//创建索引
collection.createIndex(new BasicDBObject("username", 1));
//指定索引名称
collection.ensureIndex(new BasicDBObject("age", -1), "age_index");
//创建唯一索引:如果数据重复将会报错
//com.mongodb.MongoException$DuplicateKey: E11000 duplicate key error index: sample.user.$age_name_index  dup key
collection.ensureIndex(new BasicDBObject("age", -1).append("username", 1), "age_name_index", true);
//根据索引名称删除
collection.dropIndex("username_1");
//删除索引索引
collection.dropIndexes();

 

3、其他

1、索引与执行计划

现在表sample有10w数据内容如下:

{"username":"robin-i", "age":i,"info":{"title":"jee","salary":i}} 

根据条件查询

collection.find(new BasicDBObject("username", "robin-123")) 

这里通过对username建立索引来查看其执行计划:

//对username建立升序的索引
collection.ensureIndex(new BasicDBObject("username", 1), "username_index"); 
//通过DbCursor的explain()来查看执行计划
collection.find(new BasicDBObject("username", "robin-123")).explain()

下面是没有建索引和建立索引后两者的执行计划:

{ "cursor" : "BasicCursor" , "nscanned" : 100000 , "nscannedObjects" : 100000 , "n" : 1 , "millis" : 66 , "nYields" : 0 , "nChunkSkips" : 0 , "isMultiKey" : false , "indexOnly" : false , "indexBounds" : { } , "allPlans" : [ { "cursor" : "BasicCursor" , "indexBounds" : { }}] , "oldPlan" : { "cursor" : "BasicCursor" , "indexBounds" : { }}}
{ "cursor" : "BtreeCursor username_index" , "nscanned" : 1 , "nscannedObjects" : 1 , "n" : 1 , "millis" : 0 , "nYields" : 0 , "nChunkSkips" : 0 , "isMultiKey" : false , "indexOnly" : false , "indexBounds" : { "username" : [ [ "robin-123" , "robin-123"]]} , "allPlans" : [ { "cursor" : "BtreeCursor username_index" , "indexBounds" : { "username" : [ [ "robin-123" , "robin-123"]]}}]}

重点关注cursor、nscanned、n、millis等参数:

cursor: 这里出现的是”BasicCursor"和"BtreeCursor username_index"。就是说前者使用了表扫描,后者使用了索引
nscanned: 前者没有索引扫描了10w条数据,而后者仅扫描了1条,结果已很明显
n: 这里是1,也就是最终返回了1个文档。
millis: 执行查询花费的时间,这是我们很关注的因素,前者耗时66ms,而有索引的0ms

 

2、聚合

在mongodb官网有介绍具体用法http://www.mongodb.org/display/DOCS/Aggregation这里主要介绍java中对聚合的一些支持,包括count、sort、distinct、group等,对高级的mapreduce并不涉及

2.1、count

//会立即返回该文档的记录数
collection.count()
//返回匹配的数量
collection.count(DBObject query)

 

2.2、sort

sort是对结果集的操作,故DBCursor中

DBCursor cursor = collection.find().sort(new BasicDBObject("username", 1));

这个方法必须要在从DBCursor获取对象之前调用

 

2.3、distinct

对指定的字段去重复查询

{ "_id" : ObjectId("5098d9c782967d6792743d6c"), "name" : "Robin", "age" : 30 }
{ "_id" : ObjectId("5098d9c782967d6792743d6d"), "name" : "Lisa", "age" : 28 }
{ "_id" : ObjectId("5098d9c782967d6792743d6e"), "name" : "Amanda", "age" : 28 }
{ "_id" : ObjectId("5098d9c782967d6792743d6f"), "name" : "Ace", "age" : 27 }
{ "_id" : ObjectId("5098d9c782967d6792743d70"), "name" : "Joe", "age" : 30 }

 采用mongo的runCommand:

> db.runCommand({'distinct':'foo','key':'age'});
{
	"values" : [
		30,
		28,
		27
	],
	"stats" : {
		"n" : 5,
		"nscanned" : 5,
		"nscannedObjects" : 5,
		"timems" : 0,
		"cursor" : "BasicCursor"
	},
	"ok" : 1
}

 javaApi的支持:

List list = collection.distinct("age");
返回[30,28,27]
List list = collection.distinct("age", new BasicDBObject("name", "Robin"));
返回[30]

 

2.4、group

还是上面的数据,我们根据age来分组,将name用","分割

String reduce = "function(cur, pre){pre.name += cur.name+' '}";
GroupCommand command = new GroupCommand(collection, new BasicDBObject("age", true), null, new BasicDBObject("name", ""), reduce, null);
DBObject dbObject = collection.group(command);
{ "age" : 30.0 , "name" : "Robin Joe "} , { "age" : 28.0 , "name" : "Lisa Amanda "} , { "age" : 27.0 , "name" : "Ace "}

还有几个多态的API,根据参数不同调用,都会用到上面的GroupCommand,这里结束GroupCommand中的几个属性的意思:

    public GroupCommand(DBCollection inputCollection, DBObject keys, DBObject condition, DBObject initial, String reduce, String finalize) {
        this.input = inputCollection.getName();
        this.keys = keys;
        this.condition = condition;
        this.initial = initial;
        this.reduce = reduce;
        this.finalize = finalize;
    }
keys: 这个就是分组的key,这里是age。支持多个
initial: 初始化参数,这里指定name其值为“”,当然如果我们涉及求和我们可以指定该初始值为0
reduce: 这个函数的第一个参数是当前的文档对象,第二个参数是上一次function操作的累计对象
condition:指定过滤条件

 

2.3、命令

mongodb提供了许多命令对数据的管理或CURD操作。比如要查看数据库的状态,我们可以:

> db.runCommand({"dbStats":1})
{
	"db" : "sample",
	"collections" : 3,
	"objects" : 17,
	"avgObjSize" : 63.76470588235294,
	"dataSize" : 1084,
	"storageSize" : 11008,
	"numExtents" : 3,
	"indexes" : 1,
	"indexSize" : 8192,
	"fileSize" : 16777216,
	"ok" : 1
}

可以通过在启动参数后加上

--rest 

查看命令http://localhost:28017/_commands 或者更多的命令见http://docs.mongodb.org/manual/reference/command/

当然java驱动也提供了相应的接口:

CommandResult command = db.command("dbStats");
CommandResult res = command(new BasicDBObject("dropDatabase", 1));

另外还提供了一些列的方法可供使用,其实在javaApi中不难发现很多方法底层调用的这样的命令,如下面的删除索引的方法:

    public void dropIndexes( String name ){
        DBObject cmd = BasicDBObjectBuilder.start()
            .add( "deleteIndexes" , getName() )
            .add( "index" , name )
            .get();

        resetIndexCache();
        CommandResult res = _db.command( cmd );
        if (res.ok() || res.getErrorMessage().equals( "ns not found" ))
            return;
        res.throwOnError();
    }

这里罗列一些常见的命令,当然在javaApi中基本都有同名的方法:

//返回指定集合的统计信息
{"collStats" : collection}
//去从
{"distinct" : collection, "key" : key, "query" : query}
//删除集合数据
{"drop" : collection}
//删除当前数据库所有数据
{"dropDatabase" : 1}
//删除集合里指定的索引
{"dropIndexes" : collection, "index" : name}
分享到:
评论

相关推荐

    JAVA操作MongoDB

    java操作MongoDB简单示例文档,包括安装MongoDB 以及简单的操作:添加 数据、删除数据、修改数据等。

    mongodb java简单demo

    java连接mongodb ,创建集合,添加、修改、查询、删除文档

    MongoDB系列教程(六):java操作mongodb实例

    主要介绍了MongoDB系列教程(六):java操作mongodb实例,本文讲解了java中操作mongodb数据增加、删除、修改、查询数据等代码实例,需要的朋友可以参考下

    mongodb java测试用例

    本测试用例包括:查询数据库、查询聚类集合、查询数据、添加数据、添加多条数据、删除数据、修改数据操作,更多操作请使用者以此类推。

    mongodb-async-examples:使用MongoDB异步Java驱动程序的示例

    MongoDB异步驱动程序演示使用MongoDB异步Java驱动程序的示例该项目包含各种示例,这些示例演示了的用法。 所有的演示都是自包含的应用程序,可以快速运行以演示驱动程序的各种功能。 所有演示均假设MongoDB服务器在...

    深入云计算 MongoDB管理与开发实战详解pdf.part1

    15.1.3 Java对MongoDB数据库的基本操作 15.1.4 Java驱动的一致性 15.2 Java常用操作 15.2.1 Java对MongoDB的操作实例 15.2.2 对用户的操作 15.2.3 对集合的操作 15.2.4 对索引的操作 15.3 Java...

    MongoDB权威指南(中文版)高清

    243.2 删除文档 243.3 更新文档 253.3.1 文档替换 263.3.2 使用修改器 273.3.3 upsert 363.3.4 更新多个文档 383.3.5 返回已更新的文档 383.4 瞬间完成 413.4.1 安全操作 413.4.2 捕获“常规”...

    springMongodb参考文档中文版

    4.其他帮助资源 4.1。支持 4.1.1。社区论坛 4.1.2。专业支持 4.2。发展之后 5.新&值得注意的 5.1。Spring Data MongoDB 2.1中的新特性 5.2。Spring Data MongoDB 2.0中的新特性 5.3。Spring Data MongoDB 1.10中的...

    MongoDB_Demo

    //2、通过uri方式连接MongoDB uri根据选择的数据库修改登录用户dzs MongoClientURI mongoClientUri =new MongoClientURI(uri); MongoClient mongoclient =new MongoClient(mongoClientUri); //连接到数据库 ...

    电子书:MongoDB权威指南(中文版)

    263.3.2 使用修改器 273.3.3 Upsert 363.3.4 更新多个文档 383.3.5 返回已更新的文档 383.4 瞬间完成 413.4.1 安全操作 413.4.2 捕获“常规”错误 423.5 请求和连接 43第4 章 查询 454.1 find ...

    springboot整合mongodb

    mongodb版本号3.2,需手动开启http服务,启动时使用命令 ./mongod --httpinterface 新增 修改 删除 查询 排序 分页 可查看: https://blog.csdn.net/m0_37132783/article/details/96992439

    java操作geoserver的工具类GeoServer,配合geoserver-manager包使用

    java操作geoserver的工具类,包含mongodb和sqlserver创建数据存储的对象, 封装好了图层的shp发布,数据库空间表发布,图层列表查询,删除,发布样式,设置图层默认样式,发布带样式的空间表,删除样式,查询图层中心...

    深入云计算 MongoDB管理与开发实战详解pdf.part2

    15.1.3 Java对MongoDB数据库的基本操作 15.1.4 Java驱动的一致性 15.2 Java常用操作 15.2.1 Java对MongoDB的操作实例 15.2.2 对用户的操作 15.2.3 对集合的操作 15.2.4 对索引的操作 15.3 Java...

    java中间件学习笔记

    java中间件学习笔记1 Mongodb安装1.1 单机安装1.2 主从复制架构原理和缺陷1.3 复制集Replica Sets1.3.1 复制集是什么1.3.2 使用复制集的优势1.3.3 复制集集群架构原理1.3.4 复制集搭建1.3.4.1 节点的动态增删1.3.4.2...

    详解MongoDB中创建集合与删除集合的操作方法

    因为MongoDB属于NoSQL,所以集合collection相当于关系型数据库中的表table,这里我们就来详解MongoDB中创建集合与删除集合的操作方法:

    snmp安装包rpm_mongodb4复制集部署_最新版

    安装snmp服务需要的rpm包: perl-Data-Dumper-2.145-3.el7.x86_64.rpm ...安装步骤: ... 例如,将这几个rpm包放在 /root目录下,然后进入这... (注意,192.168.0.200更改为自己安装snmp服务的那台机器地址)  有疑问可以来

    phpMoAdmin(MongoDB管理工具) v2.6.4.zip

    phpMoAdmin是一个用PHP开发的在线MongoDB管理工具,可用于创建、删除和修改数据库和索引,提供视图和数据搜索工具,提供数据库启动时间和内存的统计,支持JSON格式数据的导入导出。 基于Vork框架开发。 MongoDB是...

    毕业设计—基于express+redis+mongodb在线答题系统后台.zip

    毕业设计—基于express+redis+mongodb在线答题系统后台.zip Project setup(安装步骤) npm install Compiles and hot-reloads for development(运行后台) npm run server 用例描述 用例名称 描述 登录 用户输入邮箱和...

    基于mongodb+nodejs+express + vue+elemenet全栈开发带权限的管理系统源码+使用说明.zip

    基础能力强的可以在此基础上修改调整,以实现不同的功能。 一 mongodb使用 1)命令函: (mongo:代表进入mongo环境) (show dbs :显示数据库) (db当前) (use goods :切换到goods) 2)Token令牌 : 就是一个...

    nomopojo:提供不使用POJO的MongoDB REST服务的通用Java CRUD Servlet

    (至少直到我删除此警告!) 名字 nomopojo代表“ No More POJO”。 在Java / J2EE世界中,有无数种方法来将REST服务设置为Servlet,但是几乎所有方法都需要您将对象层声明为Plain Old Java Objects(也称为DTO,VO...

Global site tag (gtag.js) - Google Analytics