设为首页 收藏本站
查看: 1647|回复: 0

[经验分享] MongoDB入门学习笔记之mongo shell和java客户端

[复制链接]
发表于 2015-11-10 14:40:38 | 显示全部楼层 |阅读模式
一、数据准备      


  MongoDB提供Shell、Python、Java、Node.js、C++、C#等实现方式。本文介绍使用Shell和Java两种方式实现MongoDB的CRUD操作。首先需要导入数据,从官网下载测试数据,打开此页面:https://raw.githubusercontent.com/mongodb/docs-assets/primer-dataset/dataset.json,创建一个文件,将页面中的内容复制出来,粘贴保存,文件命名为primer-dataset.json。然后开启MongoDB服务,使用mongoimport命令将数据导入,如果collection已经存在数据库中,先将其删除:
  

mongoimport --db test --collection restaurants --drop --file primer-dataset.json
DSC0000.jpg
  
  注意,如果mongod实例(服务)运行在不同主机或端口下,应该使用--host和--port选项指定。
  



二、mongo shell



1、关于mongo shell
  mongo shell是一个交互式的JavaScript shell,它提供了强大的接口供开发者直接查询和操作数据库,mongo还提供了一个功能齐全的JavaScript环境使用MongoDB。关于mongo的使用和选项参数可以使用mongo --help查看或者查看官网http://docs.mongodb.org/manual/reference/program/mongo/在此不过多介绍。现使用mongo
shell连接到MongoDB
DSC0001.jpg
  mongo shell下键入help查看可用命令的列表及其描述
DSC0002.jpg
  例如查看DB的方法db.getName()
DSC0003.jpg
  



2、mongo shell添加数据


  • 选择使用的数据库
  

use test

  • 添加数据
  

db.restaurants.insert(
{
"address" : {
"street" : "2 Avenue",
"zipcode" : "10075",
"building" : "1480",
"coord" : [ -73.9557413, 40.7720266 ],
},
"borough" : "Manhattan",
"cuisine" : "Italian",
"grades" : [
{
"date" : ISODate("2014-10-01T00:00:00Z"),
"grade" : "A",
"score" : 11
},
{
"date" : ISODate("2014-01-16T00:00:00Z"),
"grade" : "B",
"score" : 17
}
],
"name" : "Vella",
"restaurant_id" : "41704620"
}
)看到下面信息表明数据添加成功  
DSC0004.jpg
  如果添加的文档对象没有_id字段,mongo shell会自动添加该字段,并为其设置一个自增的ObjectId对象值

3、mongo shell查询数据

(1)查询collection中的所有文档对象
  

db.restaurants.find()

  

(2)相等查询条件
  条件&#26684;式:{ <field1>:<value1>,<field2>:<value2>,...}
  


  • 通过顶层字段查询,例如查询字段borough&#20540;为Manhattan的文档对象
  

db.restaurants.find( { &quot;borough&quot;: &quot;Manhattan&quot; } )

  • 通过内嵌对象的字段查询,例如查询address内嵌文档对象字段zipcode&#20540;为10075的文档对象

db.restaurants.find( { &quot;address.zipcode&quot;: &quot;10075&quot; } )

  • 通过数组的字段查询,例如查询数组grades中包含的内嵌文档对象的字段grade&#20540;为B的文档对象
  

db.restaurants.find( { &quot;grades.grade&quot;: &quot;B&quot; } )
(3)含操作符的查询条件
  条件&#26684;式:{ <field1>:{<operator1>:<value1>}}
  


  • 大于操作符$gt,例如查询数组grades中包含的内嵌文档对象的字段score&#20540;大于30的文档对象
  

db.restaurants.find( { &quot;grades.score&quot;: { $gt: 30 } } )

  


  • 小于操作符,例如查询数组grades中包含的内嵌文档对象的字段score&#20540;小于10的文档对象
  

db.restaurants.find( { &quot;grades.score&quot;: { $lt: 10 } } )
(4)联合查询
  


  • 逻辑与,例如
  

db.restaurants.find( { &quot;cuisine&quot;: &quot;Italian&quot;, &quot;address.zipcode&quot;: &quot;10075&quot; } )
  
  


  • 逻辑或,例如
  

db.restaurants.find(
{ $or: [ { &quot;cuisine&quot;: &quot;Italian&quot; }, { &quot;address.zipcode&quot;: &quot;10075&quot; } ] }
)
(5)查询结果排序
  


  • 将查询结果按字段排序,参数1表示升序,-1表示降序,例如

db.restaurants.find().sort( { &quot;borough&quot;: 1, &quot;address.zipcode&quot;: 1 } )
4、mongo shell更新数据

(1)更新指定字段&#20540;




  • 更新顶层字段,$set操作符表示在Document中设置字段&#20540; ,$currentDate操作符表示设置字段&#20540;为当前时间,第一个参数为更新条件,例如
  
  

db.restaurants.update(
{ &quot;name&quot; : &quot;Juni&quot; },
{
$set: { &quot;cuisine&quot;: &quot;American (New)&quot; },
$currentDate: { &quot;lastModified&quot;: true }
}
)
  


  • 更新内嵌对象的字段&#20540;,例如
  

db.restaurants.update(
{ &quot;restaurant_id&quot; : &quot;41156888&quot; },
{ $set: { &quot;address.street&quot;: &quot;East 31st Street&quot; } }
)
  
  


  • 更新多个文档对象
  默认情况下,update()方法只会更新一个文档(第一个匹配的),可以在该方法中添加multi参数选项更新所有匹配更新条件的文档,例如
  

db.restaurants.update(
{ &quot;address.zipcode&quot;: &quot;10016&quot;, cuisine: &quot;Other&quot; },
{
$set: { cuisine: &quot;Category To Be Determined&quot; },
$currentDate: { &quot;lastModified&quot;: true }
},
{ multi: true}
)
(2)替换文档
  
  同样使用update()方法,第一个参数是匹配条件,第二个参数是替换的新文档对象,新文档的字段和原文档可以完全不同,但是_id字段是不可变的,仍为原来的&#20540;,新文档可以不含_id字段,但是如果包含了_id字段,它的&#20540;就必须和原有&#20540;相同,例如
  

db.restaurants.update(
{ &quot;restaurant_id&quot; : &quot;41704620&quot; },
{
&quot;name&quot; : &quot;Vella 2&quot;,
&quot;address&quot; : {
&quot;coord&quot; : [ -73.9557413, 40.7720266 ],
&quot;building&quot; : &quot;1480&quot;,
&quot;street&quot; : &quot;2 Avenue&quot;,
&quot;zipcode&quot; : &quot;10075&quot;
}
}
)

5、mongo shell删除数据
  


  • 删除匹配条件的所有文档
  
  

db.restaurants.remove( { &quot;borough&quot;: &quot;Manhattan&quot; } )
  


  • 删除单个文档
  默认情况下,remove()方法删除匹配条件的所有文档,使用justOne参数选项只删除匹配条件的一个文档,例如
  

db.restaurants.remove( { &quot;borough&quot;: &quot;Queens&quot; }, { justOne: true } )
  


  • 删除全部文档
  

db.restaurants.remove( { } )
  


  • 删除collection

remove()只删除collection中的文档,删除collection需要使用drop()方法
  

db.restaurants.drop()

6、mongo shell聚合操作
  MongoDB可以执行聚合操作,例如按指定key分组然后评估不同的组。使用aggregate()方法去执行一个基于段的聚合操作,该方法参数为一个数组,数组中的&#20540;为stage,可以理解为一段操作,aggregate()按参数数组中的stage顺序执行,它描述了数据处理的步骤,有点类&#20284;Linux中的管道操作
  &#26684;式:db.collection.aggregate([<stage1>,<stage2>,...])


  • 按字段分组并统计个数

例如按字段borough&#20540;分组然后,使用累加器统计每组文档个数,$group的字段需要$前缀  

db.restaurants.aggregate(
[
{ $group: { &quot;_id&quot;: &quot;$borough&quot;, &quot;count&quot;: { $sum: 1 } } }
]
);
  
  结果集由以下文档构成


DSC0005.jpg


  • 文档过滤和分组

使用$match过滤文档,语法和查询操作语法一样。下面例子过滤出borough等于Queens和cuisine等于Brazilian的文档作为$group的输入,然后按address.zipcode的&#20540;进行分组和统计  

db.restaurants.aggregate(
[
{ $match: { &quot;borough&quot;: &quot;Queens&quot;, &quot;cuisine&quot;: &quot;Brazilian&quot; } },
{ $group: { &quot;_id&quot;: &quot;$address.zipcode&quot; , &quot;count&quot;: { $sum: 1 } } }
]
);结果集由以下文档构成

DSC0006.jpg   

7、mongo shell创建索引
  索引支持高效的查询,MongoDB会自动在_id字段上添加索引。mongo shell使用createIndex()方法为一个或多个字段创建索引,只有当字段索引不存在是才会创建
  &#26684;式:{ <field1>:<type1>,...}
  type为1表示升序索引,-1表示降序索引


  • 创建单字段索引

db.restaurants.createIndex( { &quot;cuisine&quot;: 1 } )
  该方法调用返回一个包含操作状态的文档
DSC0007.jpg


  成功创建索引之后,numIndexesAfter&#20540;大于“numIndexesBefore&#20540;。




  • 创建复合索引

db.restaurants.createIndex( { &quot;cuisine&quot;: 1, &quot;address.zipcode&quot;: -1 } ) DSC0008.jpg



三、Java客户端
      使用Java客户端操作MongoDB,首先需要下载java driver和BSON类库,下载地址https://oss.sonatype.org/content/repositories/releases/org/mongodb/mongo-java-driver/3.0.2/。这个jar包全部包含了 DSC0009.jpg
  使用java客户端实现MongoDB的CRUD操作与使用mongo shell很相&#20284;,下面贴出全部代码,过程步骤全部写到注释里了

package dao;
import static com.mongodb.client.model.Sorts.ascending;
import static com.mongodb.client.model.Filters.*;
import static java.util.Arrays.asList;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import org.bson.Document;
import com.mongodb.AggregationOptions;
import com.mongodb.Block;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.mongodb.client.AggregateIterable;
/**
*
* @ClassName: MongoDBTest
* @Description:
* @author jianjian
* @date 2015年8月28日 上午10:58:48
*
*/
public class MongoDBTest {
private static volatile MongoDBTest instance;
private static MongoClient mongoClient;
private static MongoDatabase db;
private static MongoCollection<Document> collection;
private MongoDBTest(){
init();
}
public static MongoDBTest getInstance(){
if(null == instance){
synchronized(MongoDBTest.class){
if(null == instance){
instance = new MongoDBTest();
}
}
}
return instance;
}
private void init() {
//创建MongoDB实例,默认host:localhost,port:27017,可以使用其他构造函数指定host和port
mongoClient = new MongoClient();
//访问test数据库,不存在则创建
db = mongoClient.getDatabase(&quot;test&quot;);
//获取名为restaurants的MongoCollection对象,如果不存在则创建一个
collection = db.getCollection(&quot;restaurants&quot;);
}
/**
*
* @Title:
* @Description:插入数据
* @param:
* @return:
* @throws:
*/
public void insertData() throws ParseException{
DateFormat format = new SimpleDateFormat(&quot;yyyy-MM-dd'T'HH:mm:ss'Z'&quot;, Locale.ENGLISH);
//创建文档对象,以K-V方式组织数据,使用LinkedHashMap作为数据存储结构
Document document =new Document(&quot;address&quot;,
new Document()
.append(&quot;street&quot;, &quot;2 Avenue&quot;)
.append(&quot;zipcode&quot;, &quot;10075&quot;)
.append(&quot;building&quot;, &quot;1480&quot;)
.append(&quot;coord&quot;, asList(-73.9557413, 40.7720266)))
.append(&quot;borough&quot;, &quot;Manhattan&quot;)
.append(&quot;cuisine&quot;, &quot;Italian&quot;)
.append(&quot;grades&quot;, asList(
new Document()
.append(&quot;date&quot;, format.parse(&quot;2014-10-01T00:00:00Z&quot;))
.append(&quot;grade&quot;, &quot;A&quot;)
.append(&quot;score&quot;, 11),
new Document()
.append(&quot;date&quot;, format.parse(&quot;2014-01-16T00:00:00Z&quot;))
.append(&quot;grade&quot;, &quot;B&quot;)
.append(&quot;score&quot;, 17)))
.append(&quot;name&quot;, &quot;Vella&quot;)
.append(&quot;restaurant_id&quot;, &quot;41704620&quot;);
//插入数据,文档对象必须有_id字段,如果没有驱动会自动添加该字段,并为它设一个ObjectId值
collection.insertOne(document);
}
/**
*
* @Title:
* @Description:查询数据
* @param:
* @return:
* @throws:
*/
public void findData(){
//1.返回collection中所有的文档对象
//FindIterable<Document> iterable = collection.find();
//2.查询字段borough值为Manhattan的文档对象(顶层字段)
//FindIterable<Document> iterable = collection.find(new Document(&quot;borough&quot;, &quot;Manhattan&quot;));
//3.使用 Filters类提供的eq方法查询字段borough值为Manhattan的文档对象
//FindIterable<Document> iterable = collection.find(eq(&quot;borough&quot;, &quot;Manhattan&quot;));
//4.查询address内嵌文档对象字段zipcode值为10075的文档对象
//FindIterable<Document> iterable = collection.find(new Document(&quot;address.zipcode&quot;, &quot;10075&quot;));
//5.查询数组grades中包含的内嵌文档对象的字段grade值为B的文档对象(所要查询的文档对象中的数组值也是文档对象,拗口/(ㄒoㄒ)/~~)
//FindIterable<Document> iterable = collection.find(new Document(&quot;grades.grade&quot;, &quot;B&quot;));
//6.使用操作符$gt查询数组grades中包含的内嵌文档对象的字段score值大于10的文档对象
//FindIterable<Document> iterable = collection.find(new Document(&quot;grades.score&quot;, new Document(&quot;$gt&quot;, 10)));
//7.对于6的查询使用Filters类提供的gt方法结果一致
//FindIterable<Document> iterable = collection.find(gt(&quot;grades.score&quot;, 10));
//8.使用操作符$lt查询数组grades中包含的内嵌文档对象的字段score值小于30的文档对象
//FindIterable<Document> iterable = collection.find(new Document(&quot;grades.score&quot;, new Document(&quot;$lt&quot;, 30)));
//9.对于8的查询使用Filters类提供的lt方法结果一致
//FindIterable<Document> iterable = collection.find(lt(&quot;grades.score&quot;, 30));
//10.联合查询(逻辑与)
//FindIterable<Document> iterable = collection.find(new Document(&quot;cuisine&quot;, &quot;Italian&quot;).append(&quot;address.zipcode&quot;, &quot;10075&quot;));
//11.联合查询Filters类提供的and方法实现
//FindIterable<Document> iterable = collection.find(and(eq(&quot;cuisine&quot;, &quot;Italian&quot;), eq(&quot;address.zipcode&quot;, &quot;10075&quot;)));
//12.联合查询(逻辑或)数组里的元素是或的操作数
//FindIterable<Document> iterable = collection.find(
//        new Document(&quot;$or&quot;, asList(new Document(&quot;cuisine&quot;, &quot;Italian&quot;),
//                new Document(&quot;address.zipcode&quot;, &quot;10075&quot;))));
//13.联合查询Filters类提供的or方法实现
//FindIterable<Document> iterable = collection.find(or(eq(&quot;cuisine&quot;, &quot;Italian&quot;), eq(&quot;address.zipcode&quot;, &quot;10075&quot;)));
//14.将查询结果按字段排序参数1表示升序,-1表示降序
//FindIterable<Document> iterable = collection.find()
//        .sort(new Document(&quot;borough&quot;, 1).append(&quot;address.zipcode&quot;, 1));
//15.使用Sort类提供的ascending静态方法实现查询结果升序排列(descending静态方法实现降序)
FindIterable<Document> iterable = collection.find().sort(ascending(&quot;borough&quot;, &quot;address.zipcode&quot;));
//迭代结果,为每个文档对象申请一个Block(其实就是输结果)
iterable.forEach(new Block<Document>() {
@Override
public void apply(final Document document) {
// TODO Auto-generated method stub
System.out.println(document);
}
});
}
/**
*
* @Title:
* @Description:更新数据
* @param:
* @return:
* @throws:
*/
public void updateData(){
//更新顶层字段,$set操作符表示在Document中设置字段值 ,$currentDate操作符表示设置字段值为当前时间。updateOne方法即使匹配多个Document也只会更新一个
UpdateResult updateResult = collection.updateOne(new Document(&quot;name&quot;, &quot;Vella&quot;),
new Document(&quot;$set&quot;, new Document(&quot;cuisine&quot;, &quot;American (New)&quot;))
.append(&quot;$currentDate&quot;, new Document(&quot;lastModified&quot;, true)));
System.out.println(updateResult.toString());
//更新多个Document
collection.updateMany(new Document(&quot;address.zipcode&quot;, &quot;10016&quot;).append(&quot;cuisine&quot;, &quot;Other&quot;),
new Document(&quot;$set&quot;, new Document(&quot;cuisine&quot;, &quot;Category To Be Determined&quot;))
.append(&quot;$currentDate&quot;, new Document(&quot;lastModified&quot;, true)));
//替换整个Document,但_id字段不会变
collection.replaceOne(new Document(&quot;name&quot;, &quot;Juli&quot;),
new Document(&quot;address&quot;,
new Document()
.append(&quot;street&quot;, &quot;2 Avenue&quot;)
.append(&quot;zipcode&quot;, &quot;10075&quot;)
.append(&quot;building&quot;, &quot;1480&quot;)
.append(&quot;coord&quot;, asList(-73.9557413, 40.7720266)))
.append(&quot;name&quot;, &quot;Vella 2&quot;));
}
/**
*
* @Title:
* @Description:删除数据
* @param:
* @return:
* @throws:
*/
public void removeData(){
//删除条件和查询操作使用相同的结果和语法
//DeleteResult  deleteResult = collection.deleteMany(new Document(&quot;borough&quot;, &quot;shenzhen&quot;));
//System.out.println(deleteResult.toString());
//删除collection中所有的Document,但collection自身和collection的索引还在
//collection.deleteMany(new Document());
//删除整个collection,连同索引一起删除
collection.drop();
}
/**
*
* @Title:
* @Description:聚合操作
* @param:
* @return:
* @throws:
*/
public void aggregation(){
//1、按字段borough值分组然后,使用累加器统计每组文档个数,$group的字段需要$前缀
//AggregateIterable<Document> iterable = collection.aggregate(asList(
//new Document(&quot;$group&quot;, new Document(&quot;_id&quot;, &quot;$borough&quot;).append(&quot;count&quot;, new Document(&quot;$sum&quot;, 1)))));
//2、过滤出borough等于Queens和cuisine等于Brazilian的文档作为$group的输入,让你按address.zipcode的值进行分组和统计
AggregateIterable<Document> iterable = collection.aggregate(asList(
new Document(&quot;$match&quot;, new Document(&quot;borough&quot;, &quot;Queens&quot;).append(&quot;cuisine&quot;, &quot;Brazilian&quot;)),
new Document(&quot;$group&quot;, new Document(&quot;_id&quot;, &quot;$address.zipcode&quot;).append(&quot;count&quot;, new Document(&quot;$sum&quot;, 1)))));
iterable.forEach(new Block<Document>() {
@Override
public void apply(final Document document) {
System.out.println(document.toJson());
}
});
}
/**
*
* @Title:
* @Description:创建索引
* @param:
* @return:
* @throws:
*/
public void createIndex(){
//1、创建单字段索引
collection.createIndex(new Document(&quot;cuisine&quot;, 1));
//2、创建复合索引
collection.createIndex(new Document(&quot;cuisine&quot;, 1).append(&quot;address.zipcode&quot;, -1));
}
public static void main(String[] args) throws ParseException {
MongoDBTest mongoTest = MongoDBTest.getInstance();
//mongoTest.insertData();
//mongoTest.findData();
//mongoTest.updateData();
//mongoTest.removeData();
//mongoTest.aggregation();
//mongoTest.createIndex();
mongoTest.findData();
}
}

  
  总结:本文主要讲解了通过mongo shell和java两种方式对MongoDB进行CRUD操作、聚合操作以及索引的创建
  参考:https://www.mongodb.org/




  

版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-137623-1-1.html 上篇帖子: mongodb数据库的使用-管理员管理-创建超级管理员以及登陆-直接验证登陆 下篇帖子: MongoDB : Aggregation mongo聚合操作详细说明
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表