java拾遗5----Java操作Mongo入门
Java操作Mongo入门
参考:
http://api.mongodb.com/java/3.2/
http://www.runoob.com/mongodb/mongodb-java.html
https://docs.mongodb.com/manual/
1.dependency
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.2.2</version>
</dependency>
2.连接Mongo
2.1.无用户名密码验证
//连接"localhost:27017"可以直接使用无参构造new MongoClient();
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
2.2.需要用户名密码验证
//连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址
//ServerAddress()两个参数分别为 服务器地址 和 端口
ServerAddress serverAddress = new ServerAddress("localhost",27017);
List<ServerAddress> addrs = new ArrayList<ServerAddress>();
addrs.add(serverAddress);
//MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
credentials.add(credential);
//通过连接认证获取MongoDB连接
MongoClient mongoClient = new MongoClient(addrs,credentials);
3.获取操作数据库/不存在会创建
MongoDatabase db = mongoClient.getDatabase("mydb");
4.创建集合
Mongo中的集合,可以看做是数据库中的表。
db.createCollection("user");
5.获得指定集合,并遍历所有数据
MongoCollection<Document> users = db.getCollection("user");
FindIterable<Document> documents = users.find();
for (Document document : documents) {
System.out.println(document);
}
6.查询
6.1 通过Document查询条件
//查找所有name = csc的document
Document query1 = new Document("name", "csc");
FindIterable<Document> documents = users.find(query1);
for (Document d : documents) {
System.out.println(d.toJson());
}
使用运算符“$lt”,"$gt","$lte","$gte"
//age < 25
Document query2 = new Document("age", new Document("$lt", 25));
FindIterable<Document> documents = users.find(query2);
and连接多个条件
Document query3 = new Document("age", new Document("$lt", 25)).append("name", "csc");
FindIterable<Document> documents = users.find(query3);
也可以:
Document query4 = new Document("name", "csc");
query4.put("age", new Document("$lt", 25));
FindIterable<Document> documents = users.find(query4);
or连接多个条件
//name = csc || name == dqr
Document query5 = new Document("$or", Arrays.asList(new Document("name", "csc"), new Document("name", "dqr")));
FindIterable<Document> documents = users.find(query5);
between...and...
//如果这样写,会值返回age > 20的document,因为后面一个key为"age"的把前面一个覆盖了。
Document query6 = new Document("age", new Document("$lt", 23)).append("age", new Document("$gt", 20));
FindIterable<Document> documents = users.find(query6);
//正确写法:
Document query6 = new Document("age", new Document("$lt", 23).append("$gt", 20));
FindIterable<Document> documents = user.find(query6);
6.2 通过Filters指定查询条件(更简洁的做法)
相等:eq
FindIterable<Document> documents = user.find(Filters.eq("name", "csc"));
不等:ne、lt、lte、gt、gte
FindIterable<Document> documents = user.find(Filters.lte("age", 23));
in:
FindIterable<Document> documents = user.find(Filters.in("age", Arrays.asList(23,25,27)));
and:
Bson and = Filters.and(Filters.eq("name", "csc"), Filters.ne("age", 25));
FindIterable<Document> documents = user.find(and);
or:
FindIterable<Document> documents = user.find(Filters.or(Filters.eq("age",23),Filters.eq("age", 25)));
6.3 count
long cnt = user.count(Filters.eq("age", 27));
System.out.println(cnt);
6.4 sort
//按name升序
FindIterable<Document> documents = user.find().sort(Sorts.ascending("name"));
//按age将序
FindIterable<Document> documents = user.find().sort(Sorts.descending("age"));
//按name升序,name相同的按age降序
FindIterable<Document> documents = user.find().sort(Sorts.orderBy(Sorts.ascending("name"), Sorts.descending("age")));
6.5 skipe & limit
//跳过前5条(0-4),返回(5-9)共5条。
FindIterable<Document> documents = user.find().sort(Sorts.descending("age")).skip(5).limit(5);
6.6 distinct
DistinctIterable<String> name = user.distinct("name", String.class);
DistinctIterable<Integer> age = user.distinct("age", Integer.class);
for (Integer a : age) {
System.out.println(a);
}
for (String s : name) {
System.out.println(s);
}
7.添加document
7.1添加单个document
Document doc = new Document();
doc.put("name", "zhangsan");
doc.put("age", 40);
user.insertOne(doc);
7.2添加多个文档
List<Document> docs = new LinkedList<Document>();
for(int i=0; i<10; i++){
Document doc = new Document();
doc.put("name", "zhangsan"+i);
doc.put("age", 40+i);
docs.add(doc);
}
user.insertMany(docs);
8.修改document
updateOne/updateMany:
user.updateMany(Filters.eq("age", 25), new Document("$set", new Document("age", 16).append("name","xxx25")));
9.删除document
deleteOne/deleteMany:
//删除第一个符合条件的
user.deleteOne(Filters.eq("age", 17));
//删除所有符合条件的
user.deleteMany(Filters.eq("age", 17));
10.aggregate
以流水线的方式,分阶段处理document。
主要阶段:
$project
对流入的每个document进行投影操作,类似于select field1, field2, ...
可以添加新字段、或删除已存在的某些字段。
MongoClient mongo = new MongoClient();
MongoDatabase db = mongo.getDatabase("test");
MongoCollection<Document> hobby = db.getCollection("student");
hobby.insertOne(new Document("name", "csc").append("hobby", Arrays.asList("reading", "coding")));
hobby.insertOne(new Document("name", "nicky").append("hobby", Arrays.asList("game")));
hobby.insertOne(new Document("name", "jack").append("hobby", Arrays.asList("movie")));
hobby.insertOne(new Document("name", "tom").append("hobby", Arrays.asList("reading", "coding")));
hobby.insertOne(new Document("name", "lucy").append("hobby", Arrays.asList("reading", "football")));
hobby.insertOne(new Document("name", "lion").append("hobby", Arrays.asList("basketball", "football")));
AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(new Document("$project", new Document("name", 1).append("_id", 0).append("hobby", 1))));
for (Document document : aggregate) {
System.out.println(document.toJson());
}
只有_id默认输出的,不想输出该字段,需要设置为0,需要输出的其他字段需要手动设置为1.
输出结果:
{ "name" : "csc", "hobby" : ["reading", "coding"] }
{ "name" : "nicky", "hobby" : ["game"] }
{ "name" : "jack", "hobby" : ["movie"] }
{ "name" : "tom", "hobby" : ["reading", "coding"] }
{ "name" : "lucy", "hobby" : ["reading", "football"] }
{ "name" : "lion", "hobby" : ["basketball", "football"] }
$match
类似于where字句
AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(
new Document("$project", new Document("name",1).append("_id", 0).append("hobby", 1))
,new Document("$match", new Document("name", "csc"))
));
输出结果:
{ "name" : "csc", "hobby" : ["reading", "coding"] }
$limit & $skip同上面的用法
$unwind
把数组中的元素拆分为多个document。
AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(
new Document("$project", new Document("name", 1).append("_id", 0).append("hobby", 1))
,new Document("$unwind", "$hobby")
));
输出结果:
{ "name" : "csc", "hobby" : "reading" }
{ "name" : "csc", "hobby" : "coding" }
{ "name" : "nicky", "hobby" : "game" }
{ "name" : "jack", "hobby" : "movie" }
{ "name" : "tom", "hobby" : "reading" }
{ "name" : "tom", "hobby" : "coding" }
{ "name" : "lucy", "hobby" : "reading" }
{ "name" : "lucy", "hobby" : "football" }
{ "name" : "lion", "hobby" : "basketball" }
{ "name" : "lion", "hobby" : "football" }
$group
类似于group by,可以使用各种聚合操作符,常用的有:
$sum, $avg, $max, $min, $first, $last
//计算每个hobby的人数
AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(
new Document("$project", new Document("name", 1).append("_id", 0).append("hobby", 1))
,new Document("$unwind", "$hobby")
,new Document("$group", new Document("_id", "$hobby").append("count", new Document("$sum", 1)))
));
必须首先设置("_id", "$hobby"),这句的含义是group by hobby这个字段。引用字段一定要添加$打头。
如:输出每个hobby的第一个name: ("$fisrt","$name")。
AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(
new Document("$project", new Document("name", 1).append("_id", 0).append("hobby", 1))
,new Document("$unwind", "$hobby")
,new Document("$group", new Document("_id", "$hobby").append("count", new Document("$sum", 1)).append("first", new Document("$first", "$name")))
));
输出结果:
{ "_id" : "basketball", "count" : 1, "first" : "lion" }
{ "_id" : "football", "count" : 2, "first" : "lucy" }
{ "_id" : "movie", "count" : 1, "first" : "jack" }
{ "_id" : "game", "count" : 1, "first" : "nicky" }
{ "_id" : "coding", "count" : 2, "first" : "csc" }
{ "_id" : "reading", "count" : 3, "first" : "csc" }
11.mapreduce
map function
function() {
...//自定义操作
emit(key, value);
}
文档中的说明:
- In the map function, reference the current document as this within the function.
- The map function should not access the database for any reason.
- The map function should be pure, or have no impact outside of the function (i.e. side effects.)
- A single emit can only hold half of MongoDB’s maximum BSON document size.
- The map function may optionally call emit(key,value) any number of times to create an output document associating key with value.
reduce function
function(key, values) {
...//自定义操作
return result;
}
文档中的说明:
- The reduce function should not access the database, even to perform read operations.
- The reduce function should not affect the outside system.
- MongoDB will not call the reduce function for a key that has only a single value. The values argument is an array whose elements are the value objects that are “mapped” to the key.
- MongoDB can invoke the reduce function more than once for the same key. In this case, the previous output from the reduce function for that key will become one of the input values to the next reduce function invocation for that key.
- The reduce function can access the variables defined in the scope parameter.
- The inputs to reduce must not be larger than half of MongoDB’s maximum BSON document size. This requirement may be violated when large documents are returned and then joined together in subsequent reduce steps.
mapreduce demo
//统计每个年龄的人数,原理同hadoop中的map、reduce方法。
//定义一个js function,以年龄作为key,进行计数。this表示当前document
String map = "function(){emit(this.age, 1)}";//age : [1,1,1,1]
//js function, 对年龄的所有计数,累加返回key-value
String reduce = "function(key, values){ return Array.sum(values)}";
MapReduceIterable<Document> docs = user.mapReduce(map, reduce);
for (Document doc : docs) {
System.out.println(doc.toJson());
}
java拾遗5----Java操作Mongo入门的更多相关文章
- 【Java拾遗】Java transient关键字
1. transient的作用及使用方法 2. transient使用小结 3. transient使用细节--被transient关键字修饰的变量真的不能被序列化吗? 1. transient的作用 ...
- MONGODB(三)——Java操作Mongo
相比于java调用MySqlApI来操作数据库,调用Mongo要简洁容易的多.通过一个简单的样例,很容易地就可以上手 一.导入Jar包 添加Monog支持Java的jar包,这里使用的是2.9.3 & ...
- java入门学习笔记之2(Java中的字符串操作)
因为对Python很熟悉,看着Java的各种字符串操作就不自觉的代入Python的实现方法上,于是就将Java实现方式与Python实现方式都写下来了. 先说一下总结,Java的字符串类String本 ...
- 为 Java 程序员准备的 Go 入门 PPT
为 Java 程序员准备的 Go 入门 PPT 这是 Google 的 Go 团队技术主管经理 Sameer Ajmani 分享的 PPT,为 Java 程序员快速入门 Go 而准备的. 视频 这个 ...
- Java基础-SSM之Spring MVC入门篇
Java基础-SSM之Spring MVC入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spring MVC简介 1>.什么是Spring MVC 答:Sprin ...
- Java基础-SSM之mybatis快速入门篇
Java基础-SSM之mybatis快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 其实你可能会问什么是SSM,简单的说就是spring mvc + Spring + m ...
- java 对mongodb的操作
java 对mongodb的操作 1.1连单台mongodb Mongo mg = newMongo();//默认连本机127.0.0.1 端口为27017 Mongo mg = newMongo( ...
- Java学习---Excel读写操作
1.1.1. 简介 Apache POI 使用Apache POI 完成Excel读写操作 Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API ...
- Java自动化测试框架-01 - TestNG之入门篇 - 大佬的鸡肋,菜鸟的盛宴(详细教程)
TestNG是什么? TestNG按照官方的定义: TestNG是一个测试框架,其灵感来自JUnit和NUnit,但引入了一些新的功能,使其功能更强大,使用更方便. TestNG是一个开源自动化测试框 ...
随机推荐
- java自定义注解与反射
java注解与反射一.Java中提供了四种元注解,专门负责注解其他的注解,分别如下 1.@Retention元注解,表示需要在什么级别保存该注释信息(生命周期).可选的RetentionPoicy参数 ...
- python 列表,元组,字符串方法和属性
python序列包含列表[].元组().字符串三种 -------列表-------------- 一.列表基本内容 1.建立:a=[1,2,3,5],通过[ , ,], >>>b= ...
- 【MyBatis学习05】SqlMapConfig.xml文件中的配置总结
经过上两篇博文的总结,对mybatis中的dao开发方法和流程基本掌握了,这一节主要来总结一下mybatis中的全局配置文件SqlMapConfig.xml在开发中的一些常用配置,首先看一下该全局配置 ...
- Hive substr 函数截取字符串
开发中,经常进行模糊查询或者进行截取字符串进行模糊匹配,常用的就是substr函数或者substring函数. 使用语法: substr(string A, int start),substring( ...
- position与float属性的使用
1.使用float时,可以说是用于布局,取值主要有left.right.none.就是将该块的元素浮动起来,在浏览器默认的情况下,该元素的位置是为空的, 即脱离了文档流而存在,如果有其他元素,那么这些 ...
- 一键保存网页为PDF_V1.2
福利来了,“一键保存网页为PDF”发布以来最给力的功能来了: 1.支持大部分浏览器了(添加书签方式),测试IE8\IE9.谷歌.火狐可用: 2.转换组件“ephtmltopdf”无水印了,不用注册账号 ...
- iOS开发--用户点击频繁,多个异步网络请求取消问题?
一.业务环境描述 当一个view同时添加两个tableView为subView的时候,两个tableView分别为mainTable和subTable. 当用户点击mainTable上的某一条数据时, ...
- python简单处理xml文件
Python若是想从xml里读点信息,用BeautifulSoup可能会容易一点,但是如果要修改xml,BeatifulSoup就搞不定了,其实直接用lxml就好. from lxml import ...
- FreeBSD编译安装emacs,不要用ports
1. 解压emacs 2. 进入解压之后的目录,执行configure命令,大体配置如下: ./configure --with-x-toolkit=no --with-xpm=no --with-j ...
- Kafka学习(一)kafka指南(about云翻译)
kafka 权威指南中文版 问题导读 1. 为什么数据管道是数据驱动企业的一个关键组成部分? 2. 发布/订阅消息的概念及其重要性是什么? 第一章 初识 kafka 企业是由数据驱动的.我们获取信息, ...