Java操作mongoDB使用文档.docx
- 文档编号:11265758
- 上传时间:2023-02-26
- 格式:DOCX
- 页数:13
- 大小:25.90KB
Java操作mongoDB使用文档.docx
《Java操作mongoDB使用文档.docx》由会员分享,可在线阅读,更多相关《Java操作mongoDB使用文档.docx(13页珍藏版)》请在冰豆网上搜索。
Java操作mongoDB使用文档
JavaDriverforMongoDB
开发前准备:
1.MongoDB连接url(e.g.localhost:
27017)
2.mongo-java-driver-2.9.3.jar(目前最新版)
3.www.mongodb.org(用来查看api和帮助文档)
一、连接MongoDB
//MongoDB连接对象
privateMongomongoDBServer;
//根据host:
port获取MongoDB连接对象
mongoDBServer=newMongo(host,port);
//数据库名
privateStringdatabase;
//从连接对象中获得相应数据库对象
DBdb=mongoDBServer.getDB(database);
至此,我们已经打开了一个mongodb的连接,并且已经获得一个名为database的数据库(mongodb中成为collection集合)。
下面对这个集合进行增删改查操作。
进行操作前。
我们需要先使用数据库对象获取表(mongodb中的集合对象)。
//获得名为person的表(又称集合)
DBCollectiondbcol=db.getCollection("person");
二、新增操作(Add)
//新建一个map对象,将需要保存的数据放入map中
map.put("key","value");…….
//用map对象创建一个MongoDB自带的DBObject对象用作插入操作参数
DBObjectparam=newBasicDBObject(map);
//调用数据库集合对象的insert方法,传入DBObject对象执行插入操作
WriteResultresult=dbcol.insert(param);
WriteResult对象是操作返回结果,我们可以用如下方法判断操作是否出错
if(result.getError()!
=null)
{
System.out.println(result.getError());
}
至此新增操作完成。
三、修改操作(update)
修改操作其实和新增操作的方法一样,唯一不同的地方是将以往我们编写SQL语句的操作改为创建mongodb查询json串。
这里mongodb的update方法比较复杂,此处只演示其中一种方法,具体的请各位自行googleXX。
(查询参数见:
附录)
params.put("age",30);
//更新参数
DBObjectparam=newBasicDBObject("$set",params);
//更新条件
DBObjectcondition=newBasicDBObject("personId","{personId:
"hedaxing"}");
WriteResultresult=dbcol.update(condition,param);
if(result.getError()!
=null)
{
System.out.println(result.getError());
}
这里用到了"$set"操作符,更新age字段。
四、查询操作(get)
DBCollectiondbcol=db.getCollection("person");
DBObjectparam=newBasicDBObject(params);
//获取age<30的数据
DBObjectconditions=newBasicDBObject("age",newBasicDBObject("$lt",30));
DBCursorcursor=dbcol.find(condition);
for(DBObjectdbObject:
cursor)
{
System.out.println(dbObject);
}
这边只列举了最简单的查询,详细查询见附录。
五、删除
DBCollectiondbcol=db.getCollection("person");
params.put("personId","zhengchengong");
DBObjectparam=newBasicDBObject(params);
WriteResultresult=dbcol.remove(param);
if(result.getError()!
=null)
{
System.out.println(result.getError());
}
删除操作相对简单,只要将删除的条件放进map对象转换为DBObject执行DBCollection的remove操作即可。
附录
详细的官方文档:
http:
//docs.mongodb.org/manual/reference/operator/
以下截取部分简要说明:
QuerySelectors
Comparison
Name
Description
$all
Matchesarraysthatcontainallelementsspecifiedinthequery.
$gt
Matchesvaluesthataregreaterthanthevaluespecifiedinthequery.
$gte
Matchesvaluesthatareequaltoorgreaterthanthevaluespecifiedinthequery.
$in
Matchesanyofthevaluesthatexistinanarrayspecifiedinthequery.
$lt
Matchesvaluesthatarelessthanthevaluespecifiedinthequery.
$lte
Matchesvaluesthatarelessthanorequaltothevaluespecifiedinthequery.
$ne
Matchesallvaluesthatarenotequaltothevaluespecifiedinthequery.
$nin
Matchesvaluesthat donot existinanarrayspecifiedtothequery.
Logical
Name
Description
$or
Joinsqueryclauseswithalogical OR returnsalldocumentsthatmatchtheconditionsofeitherclause.
$and
Joinsqueryclauseswithalogical AND returnsalldocumentsthatmatchtheconditionsofbothclauses.
$not
Invertstheeffectofaqueryexpressionandreturnsdocumentsthatdo not matchthequeryexpression.
$nor
Joinsqueryclauseswithalogical NOR returnsalldocumentsthatfailtomatchbothclauses.
查询
Java代码
1.find({查询条件限定},{返回字段})
这是一个查询的基本语法,各个签名的作用已经说得很清楚。
下面来细细展开:
当然最开始插入一批数据以供测试:
1.db.users.insert({"_id":
1, "name":
"aroba", "age":
22, "friends":
3})
2.db.users.insert({"_id":
2, "name":
"brob", "age":
23, "friends":
4})
3.db.users.insert({"_id":
3, "name":
"robin", "age":
24, "friends":
23})
4.db.users.insert({"_id":
4, "name":
"ccrob", "age":
25, "friends":
32})
5.db.users.insert({"_id":
5, "name":
"drobin", "age":
26, "friends":
15})
6.db.users.insert({"_id":
6, "name":
"rrobin", "age":
"az", "friends":
19})
1、方法中的第一个参数:
查询条件限定是一个document结构,如为{}将默认返回所有数据
1.#查询一个年龄为27的用户:
2.db.users.find({"age":
23})
3.#查询一个年龄为27,姓名为robin的用户,相当于AND
4.db.users.find({"age":
23, "name":
"brob"})
作为文档的查询条件,可以支持更复杂的格式:
1.#查询年龄大于20且小于30的用户
2.db.users.find({"age":
{"$gt":
20, "$lte":
23}})
这里条件查询有常用的:
小于("$lt")、小于等于("$lte")、大于("$gt")、大于等于("$gte")、不等于("$ne") 。
这些条件查询对数字日期类型的字段比较适用
前面说到同时查询age和name属性,相当于AND查询。
这里来看看OR查询,主要通过"$in"和"$or" 。
对单一键有多个值与其匹配的话就用"$in",后面跟一个条件数组。
1.#查询年龄在某个范围的用户:
2.db.users.find({"age":
{"$in":
[20, 22, 25]}})
"$in"对支持的类型非常灵活,不同类型的条件可以同时查询。
与之相对应的就是"$nin",表示不在该范围内的键
1.db.users.find({"age":
{"$in":
[20, 22, 25, "az"]}})
2.db.users.find({"age":
{"$nin":
[20, 22, 25, "az"]}})
与单一键的"$in"不同的是,"$or"是包含多个可能条件的数组。
1.#年龄在某个范围内或者name在某个范围内的用户
2.db.users.find({"$or":
[{"age":
23 }, {"name":
"robin"}]})
3.db.users.find({"$or":
[{"age":
{"$in":
[ 23, 4, "az" ]} }, {"name":
"robin"}]})
2、返回字段
作为查询的第二个参数,如果没有的话是默认返回所有字段。
可以对需要的返回字段指定:
1.db.users.find({}, {"name":
1, "age":
1})
1、这个查询会返回name、age、_id字段
2、_id是默认返回,如果不要显示加上("_id":
0)
1.db.users.find({}, {"name":
1, "age":
1, "_id":
0})
3、如果某个字段如age不存在,也不抛异常
4、需要显示的字段设置为大于零的数就可以,但还是用1好理解,但如果对不需要显示的字段且不是_id设置为0或其他会抛异常
1.db.users.find({}, {"name":
1, "age":
0, "_id":
0})
这样是不行的,如果不要返回age不加上就可以了
后面还将对数组查询的返回字段做相应的说明,这里就先到此
3、几点说明
1、"$not"元条件句,用在其他任何条件上,如
1.#age>20即查询age小于等于20的用户
2.db.user.find({"age":
{"$not" :
{"$gt" :
20}}})
3.#这里查询age不是1,6,11,16...等的用户
4.db.user.find({"age":
{"$not":
{"$mod":
[5, 1]}}})
2、条件查询与更新修改器
1.#更新修改器
2.db.users.update({"age":
23},{"$set":
{"name":
"zzzz"}})
3.#条件查询
4.db.users.find({"age":
{"$gt":
20}})
条件句是内层文档键,修改器是外层文档键。
而且对同一个字段age来说可以是多个限定条件,但是修改器不能对应多个
3、null
如果某个字段的值为null,根据null来查询时可以返回该条文档,但也会返回不包含该字段的文档
1.#新增两条数据
2.>db.users.insert{ "_id" :
7, "age" :
23, "name" :
"joe" }
3.>db.users.insert{ "_id" :
8, "age" :
24, "friends" :
null, "name" :
"sam" }
查询键值为null的字段
1.>db.users.find({"friends":
null})。
这里会返回friends为null的文档,但是也会返回没有该键的文档
1.{ "_id" :
7, "age" :
23, "name" :
"joe" }
2.{ "_id" :
8, "age" :
24, "friends" :
null, "name" :
"sam" }
需要通过"$exists"来判定键值是否存在
1.> db.users.find({"friends":
{"$in":
[null],"$exists":
true}})
2.{ "_id" :
8, "age" :
24, "friends" :
null, "name" :
"rrbin" }
4、正则表达式
1.#这里会返回所有name中包含rob字段的文档
2.> db.users.find({"name":
/rob/})
3.#不仅对字段值进行正则匹配,如果值本身是正则式也匹配
4、数组查询
插入几条数据测试
1.db.food.insert({"_id":
1, "fruit":
["apple", "banana", "peach"]})
2.db.food.insert({"_id":
2, "fruit":
["apple", "orange"]})
3.db.food.insert({"_id":
3, "fruit":
["banana", "peach", "orange"]})
以下是一些常用的查询方法,直接上
1.#匹配fruit中包含banana的文档
2.db.food.find({"fruit":
"banana"})
3.#必须匹配所有
4.db.food.find({"fruit":
{"$all" :
["apple", "peach"]}})
5.#精确匹配
6.db.food.find({"fruit":
["apple", "orange"]})
7.#指定下标 key.index
8.db.food.find({"fruit.2":
"peach"})
9.#查询指定长度的数组
10.db.food.find({"fruit":
{"$size" :
3}})
但是"$size"操作只能严格匹配,遇到比如要求数组大于或者小于之类的查询就无能为力了。
这里提供了解决的方案:
对文档新增size字段,每次对数组push或pop操作时,对size字段做相应的增减。
查询的时候再对字段size做相应的处理
1.db.food.update({"$push" :
{"fruit" :
"strawberry"} , "$inc" :
{"size" :
1}})
2.db.food.find({"size" :
{"$gt" :
3}})
返回数组指定子集
"$slice"用于返回数组的一个子集,支持前、后或者偏移
1.db.food.insert({"_id":
4, "fruit":
["apple", "banana", "peach", "orange", "watermelon", "lemon", "cherry"]})
2.#取前2个
3.db.food.find({"_id":
4}, {"fruit":
{"$slice":
2}})
4.#{u'_id':
4, u'fruit':
[u'apple', u'banana']}
5.#取后两个
6.db.food.find({"_id":
4}, {"fruit":
{"$slice":
-2}})
7.#{u'_id':
4, u'fruit':
[u'lemon', u'cherry']}
8.#从第2个开始取三个,这个其实达到分页的效果,但书中明确指出对大量数据skip性能下降厉害,不建议考虑这种方式
9.db.food.find({"_id":
4}, {"fruit":
{"$slice":
[2, 3]}})
10.#{u'_id':
4, u'fruit':
[u'peach', u'orange', u'watermelon']}
使用"$slice"获取数组内的值时,其他的键也会默认返回,如果不需要返回非数组内的其他键这里可以指明,与前面返回不同的是这里可以用0
1.db.food.insert({"_id":
5, "sum":
7, "fruit":
["apple", "banana", "peach", "orange", "watermelon", "lemon"]})
2.db.food.find({"_id":
5}, {"fruit":
{"$slice":
[2, 3]}, "_id":
0, "sum":
0})
3.{u'fruit':
[u'peach', u'orange', u'watermelon']}
5、查询内嵌文档
这里主要考虑匹配查询内嵌文档,考虑如下文档
1.db.users.insert({"_id":
9, "age":
23, "name":
{"first":
"joe", "last":
"sam"}})
2.db.users.insert({"_id":
10, "age":
24, "name":
{"first":
"joe", "middle":
"dd", "last":
"sam"}})
查询名字为joesam的用户
1.#查询名字为joe sam的用户
2.data = db.users.find({"name":
{"first":
"joe", "last":
"sam"}})
3.#返回第一条,实际上这相当于精确匹配,这个查询条件将严格匹配顺序、字段的数量。
其实第二条也是我们想要的结果,那么正确的写法应该是:
4.data = db.users.find({"name.first":
"joe", "name.last":
"sam"})
书中说到一种复杂情况下的查询:
joe发表的5分以上的评论:
1.db.blog.insert({"_id":
1, "content":
"....", "comments":
[{"name":
"joe", "score":
3, "comment":
"nice"}, {"name":
"sam", "score":
5, "comment":
"zzz"}, {"name":
"joe", "score":
5, "comment":
"good"}]})
2.data = db.blog.find({"comments":
{"name":
"joe", "score":
{"$gte":
5}}})
3.#这样是查不到数据的,内嵌文档要求匹配整个文档,而不是comments键
4.data = db.blog.find({"comments.name":
"joe", "comments.score":
{"$gte":
5}})
5.#这个查询会返回这条记录,其实是匹配的commets中各个键,即joe匹配第一条,score匹配第二条
6.data = db.blog.find({"comments":
{"$elemMatch":
{"name":
"joe", "score":
{"$gte":
5}}}})
6、分页
分页在前面说到"$slice"时,其实是达到分页的效果,前面也说了弊端,这里进一步说明。
这里采用limit限制返回结果,slice跳过指定数量文档,sort对查询结果排序
limit
db.users.find().limit(3)结果集超过三条返回三条,不足返回实际数量,貌似对负数不感冒,比如-2还是返回前两条,或者limit里没有偏移这个概念
skip
db.users.find().limit(3)省略结果集前三个,返回剩下的,结果集不足三个就啥都木有了,当然这个也一样,别写负数了,否则抛异常
sort
对结果集排序:
1升序,-1降序。
可支持多个键/对
1.db.users.find().sort([("name", 1), ("age", -1)])
Shell代码
1.db.users.find().sort({"name":
1,"age":
-1})
1.#这就是分页
2.db.users.find().limit
(2).sort("_id", 1)
3.db.users.find().limit
(2).skip
(2).sort("_id", 1)
4.db.users.find().limit
(2).skip(4).sort("_id", 1)
这对大数据量的skip性能影响较大,这里也提供了一些绕过的方法。
比如先取得最后一条的记录的某个唯一键,再查询大于该键的值。
可以看出这个限制条件挺多,当然容易想到的采用主键"_id",这是主键必须是数字了
还有其他的一些高级特性,如$where、随机获取、包装查询、获取一致性结果等,这里就不一一举例说明了,有兴趣的自己搜索吧。
UpdateOperators
F
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 操作 mongoDB 使用 文档