https://www.mongodb.org/dl/linux/x86_64
windows版地址
Downloads for windows (mongodb.org)
或者
MongoDB Community Download | MongoDB
tar zxvf mongodb-linux-x86_64-4.0.4.tgz
mv mongodb-linux-linux-x86_64-4.0.4 mongodb
mkdir -p mongodb/{data/db,log,conf} # cmd 使用的md命令, 使用{}可以建多个子目录
vi mongodb/conf/mgdb.conf
配置文档
https://docs.mongodb.com/v2.4/reference/configuration-options/
dbpath=/soft/mongodb/data/db #数据文件存放目录
logpath=/soft/mongodb/log/mongodb.log #日志文件存放目录
port=27017 #端口,默认 27017,可以自定义
logappend=true #开启日志追加添加日志
fork=true #以守护程序的方式启用,即在后台运行
bind_ip=0.0.0.0 #本地监听 IP,0.0.0.0 表示本地所有 IP
auth=false #是否需要验证权限登录(用户名和密码)
修改环境变量
vi /etc/profile
export MONGODB_HOME=/soft/mongodb
export PATH=$PATH:$MONGODB_HOME/bin
source /etc/profile
配置开机启动
vi /usr/lib/systemd/system/mongodb.service
[Unit]
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
RuntimeDirectory=mongodb
PIDFile=/soft/mongodb/data/db/mongod.lock
ExecStart=/soft/mongodb/bin/mongod --config /soft/mongodb/conf/mgdb.confExecStop=/soft/mongodb/bin/mongod --shutdown --config /soft/mongodb/conf/mgdb.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
开机启动
systemctl daemon-reload
systemctl start mongodb
systemctl enable mongodb
启动 mongodb
service mongodb stop
service mongodb start
https://docs.mongodb.com/v4.0/reference/configuration-options/#storage.dbPath
storage:
dbPath: "/soft/mongodb/data/db"
systemLog:
destination: file
path: "/soft/mongodb/log/mongodb.log"
net:
bindIp: 0.0.0.0
port: 27017
processManagement:
fork: true
setParameter:
enableLocalhostAuthBypass: false
Install MongoDB Community on Windows using msiexec.exe — MongoDB Manual
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cRQit4w2-1660461785660)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207300753520.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e0ogwBOE-1660461785661)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207300753027.png)]
配置数据目录和日志目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qB1n2165-1660461785662)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207300754544.png)]
启动: 界面安装可能已经启动了
mongod.exe --dbpath D:\MongoDB\Server\4.0\data
检测是否启动: http://localhost:27017
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PNVfknLP-1660461785662)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207300802116.png)]
为了方便使用, 可以配置下环境变量
mongo_home=D:\MongoDB\Server\4.0
path=%mongo_home%\bin
使用mongo.exe客户端连接: 如果没有配置环境变量, 需要进入目录执行
mongo.exe
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5FpA6RSB-1660461785663)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207300808693.png)]
默认有个test的库
mongod --bind_ip 0.0.0.0 --logpath %mongo_home%\log\mongo.log --logappend --dbpath %mongo_home%\data ^
--port 27017 --serviceName "MongoDB Server" --serviceDisplayName "MongoDB Server" --install
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h0sIvPRv-1660461785663)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207300813787.png)]
win+r
services.msc
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sZv11wxi-1660461785664)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207300815253.png)]
romomongo
https://studio3t.com/download-studio3t-free
navicat
{
"_id" : ObjectId("59f938235d93fc4af8a37114"),
"username" : "lison",
"country" : "in11digo",
"address" : {
"aCode" : "邮编",
"add" : "d11pff"
},
"favorites" : {
"movies" : ["杀破狼 2","1dushe","雷神 1"],
"cites" : ["1sh","1cs","1zz"]
},
"age" : 18,
"salary":NumberDecimal("2.099"),
"lenght" :1.79
}
查询sql
// 查询
select * from users where favorites.cites has "深圳"、"北京";
db.users.find({"favorites.cities":{"$all":["深圳", "北京"]}});
// 更新
update users set age=6 where username = 'lison';
db.users.update({"username":"lison"},{"$set":{"age":6}});
// 删除
delete from users where username = 'lison';
db.users.deleteMany({"username":"lison"});
// 插入
insert into users("username", "conuty") values("lison", "深圳");
var user1 = {
"username" : "lison",
"country" : "china",
"address" : {
"aCode" : "411000",
"add" : "长沙"
},
"favorites" : {
"movies" : ["杀破狼2","战狼","雷神1"],
"cites" : ["长沙","深圳","上海"]
},
"age" : 18,
"salary":NumberDecimal("18889.09"),
"lenght" :1.79
};
db.users.insert(user1);
复杂点的查询
// like查询
select * from users where username like '%s%' and (country= English or country= USA);
// $regex使用
db.users.find({"$and":[{"username":{"$regex":".*s.*"}},{"$or":[{"country":"English"},{"country":"USA"}]}]});
// 更新集合
update users set favorites.movies add "小电影2 ", "小电影3" where favorites.cites has "东莞";
// $each, $addToSet使用
db.users.updateMany({"favorites.cities":"东莞"},{"$addToSet":{"favorites.movies":{"$each":["小电影2 ", "小电影3"]}}});
关系数据的事务
begin
update users set lenght= lenght-1 where username = ‘james’
update users set lenght= lenght+1 where username = ‘lison’
commit
错误示例
s = db.getMongo().startSession()
s.startTransaction()
db.users.update({"username" : "james"},{"$inc":{"lenght":-1}})
db.users.update({"username" : "lison"},{"$inc":{"lenght":1}})
s.commitTransaction()
s.abortTransaction()
以下示例必须要在集群环境下才可以使用(复制集)
var s = db.getMongo().startSession(); // 获取会话
s.startTransaction(); // 开启事务
var usersCollection = s.getDatabase("lison").users; // 通过会话获取数据的集合信息
usersCollection.update({"username" : "james"},{"$inc":{"lenght":-1}});
usersCollection.update({"username" : "lison"},{"$inc":{"lenght":1}});
s.commitTransaction(); // 提交事务
s.abortTransaction(); // 中断回滚事务
pom依赖坐标
<dependency>
<groupId>org.mongodbgroupId>
<artifactId>mongo-java-driverartifactId>
<version>3.11.2version>
dependency>
Document类的特点
本质就是一个map, 可以序列化, 实现了Bson的toBsonDocument方法用来获取BsonDocument; 所以当作一个map来操作即可
public class Document implements Map<String, Object>, Serializable, Bson {
private final LinkedHashMap<String, Object> documentAsMap; // 存放数据的LinkedhashMap
// append就是对put的封装, 并使用链式调用返回this, get也是封装了map的get
public Document append(final String key, final Object value) {
documentAsMap.put(key, value);
return this;
}
}
实例化db,doc,client
//数据库
private MongoDatabase db;
//文档集合
private MongoCollection<Document> doc;
//连接客户端(内置连接池)
private MongoClient client;
@Before
public void init() {
/*client = new MongoClient("localhost", 27017);*/
List<ServerAddress> asList =
Arrays.asList(new ServerAddress("localhost", 27018), new ServerAddress("localhost", 27017),
new ServerAddress("localhost", 27019));
client = new MongoClient(asList);
/* client = new MongoClient("localhost", 27031);*/
db = client.getDatabase("lison");
doc = db.getCollection("users");
}
插入数据
@Test
public void insertDemo() {
Document doc1 = new Document();
doc1.append("username", "cang");
doc1.append("country", "USA");
doc1.append("age", 20);
doc1.append("lenght", 1.77f);
doc1.append("salary", new BigDecimal("6565.22"));//存金额,使用bigdecimal这个数据类型
//添加“address”子文档
Map<String, String> address1 = new HashMap<String, String>();
address1.put("aCode", "0000");
address1.put("add", "xxx000");
doc1.append("address", address1);
//添加“favorites”子文档,其中两个属性是数组
Map<String, Object> favorites1 = new HashMap<String, Object>();
favorites1.put("movies", Arrays.asList("aa", "bb"));
favorites1.put("cites", Arrays.asList("东莞", "东京"));
doc1.append("favorites", favorites1);
Document doc2 = new Document();
...
//使用insertMany插入多条数据
doc.insertMany(Arrays.asList(doc1, doc2));
}
查询数据
@Test
public void testFind() {
final List<Document> ret = new ArrayList<>();
//block接口专门用于处理查询出来的数据
Consumer<Document> printDocument = new Consumer<Document>() {
@Override
public void accept(Document document) {
System.out.println(document);
ret.add(document);
}
};
//select * from users where favorites.cites has "东莞"、"东京"
//db.users.find({ "favorites.cites" : { "$all" : [ "东莞" , "东京"]}})
Bson all = Filters.all("favorites.cites", Arrays.asList("东莞", "东京"));//定义数据过滤器,喜欢的城市中要包含"东莞"、"东京"
FindIterable<Document> find = doc.find(all);
find.forEach(printDocument); // printDocument是定义一个如何处理数据的action, forEach是定义一个如何处理数据的框架, 所以框架是固定的, 但是action可以切换
System.out.println("------------------>" + String.valueOf(ret.size()));
ret.removeAll(ret);
//select * from users where username like '%s%' and (contry= English or contry = USA)
// db.users.find({ "$and" : [ { "username" : { "$regex" : ".*c.*"}} , { "$or" : [ { "country" : "English"} , { "country" : "USA"}]}]})
String regexStr = ".*c.*";
Bson regex = Filters.regex("username", regexStr);//定义数据过滤器,username like '%s%'
Bson or = Filters.or(Filters.eq("country", "English"),
Filters.eq("country", "USA"));//定义数据过滤器,(contry= English or contry = USA)
Bson and = Filters.and(regex, or);
FindIterable<Document> find2 = doc.find(and);
find2.forEach(printDocument);
System.out.println("------------------>" + String.valueOf(ret.size()));
}
更新数据
@Test
public void testUpdate() {
//update users set age=6 where username = 'lison'
// db.users.updateMany({ "username" : "lison"},{ "$set" : { "age" : 6}},true)
Bson eq = Filters.eq("username", "cang");//定义数据过滤器,username = 'cang'
Bson set = Updates.set("age", 8);
UpdateResult updateMany = doc.updateMany(eq, set);
System.out.println("------------------>" + String.valueOf(updateMany.getModifiedCount()));//打印受影响的行数
//update users set favorites.movies add "小电影2 ", "小电影3" where favorites.cites has "东莞"
//db.users.updateMany({ "favorites.cites" : "东莞"}, { "$addToSet" : { "favorites.movies" : { "$each" : [ "小电影2 " , "小电影3"]}}},true)
Bson eq2 = Filters.eq("favorites.cites", "东莞");//定义数据过滤器,favorites.cites has "东莞"
Bson addEachToSet =
Updates.addEachToSet("favorites.movies", Arrays.asList("小电影2 ", "小电影3"));
UpdateResult updateMany2 = doc.updateMany(eq2, addEachToSet);
System.out.println("------------------>" + String.valueOf(updateMany2.getModifiedCount()));
}
删除数据
@Test
public void testDelete() {
//delete from users where username = ‘cang’
//db.users.deleteMany({ "username" : "cang"} )
Bson eq = Filters.eq("username", "cang");//定义数据过滤器,username='cang'
DeleteResult deleteMany = doc.deleteMany(eq);
System.out.println("------------------>" + String.valueOf(deleteMany.getDeletedCount()));//打印受影响的行数
//delete from users where age >8 and age <25
//db.users.deleteMany({"$and" : [ {"age" : {"$gt": 8}} , {"age" : {"$lt" : 25}}]})
Bson gt = Filters.gt("age", 8);//定义数据过滤器,age > 8,所有过滤器的定义来自于Filter这个包的静态方法,需要频繁使用所以静态导入
// Bson gt = Filter.gt("age",8);
Bson lt = Filters.lt("age", 25);//定义数据过滤器,age < 25
Bson and = Filters.and(gt, lt);//定义数据过滤器,将条件用and拼接
DeleteResult deleteMany2 = doc.deleteMany(and);
System.out.println("------------------>" + String.valueOf(deleteMany2.getDeletedCount()));//打印受影响的行数
}
事务操作
@Test
public void testTransaction() {
// begin
// update users set lenght= lenght-1 where username = ‘james’
// update users set lenght= lenght+1 where username = ‘lison’
// commit
ClientSession clientSession = client.startSession();
clientSession.startTransaction();
Bson eq = Filters.eq("username", "james");// 带等于的话就是lte,gte, e出现在后面, 很合理, 因为等于也在后面
Bson inc = Updates.inc("lenght", -1);
doc.updateOne(clientSession, eq, inc);
Bson eq2 = Filters.eq("username", "lison");
Bson inc2 = Updates.inc("lenght", 1);
doc.updateOne(clientSession, eq2, inc2);
clientSession.commitTransaction();
//clientSession.abortTransaction();
}
pojo类(省略getset方法): 数据封装就是pojo的封装
Favorites
public class Favorites {
private List<String> movies;
private List<String> cites;
}
Address
public class Address {
private String aCode;
private String add;
}
User: 只需要这个添加Document注解即可
@Document(collection="users")
public class User {
private ObjectId id;
private String username;
private String country;
private Address address;
private Favorites favorites;
private int age;
private BigDecimal salary;
private float lenght;
}
初始化db,doc,client
private MongoDatabase db;
private MongoCollection<User> doc;
private MongoClient client;
@Before
public void init() {
//编解码器的list
List<CodecRegistry> codecResgistes = new ArrayList<>();
//list加入默认的编解码器集合
codecResgistes.add(MongoClient.getDefaultCodecRegistry());
//生成一个pojo的编解码器
CodecRegistry pojoCodecRegistry =
CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build());
//list加入pojo的编解码器
codecResgistes.add(pojoCodecRegistry);
//通过编解码器的list生成编解码器注册中心
CodecRegistry registry = CodecRegistries.fromRegistries(codecResgistes);
//把编解码器注册中心放入MongoClientOptions
//MongoClientOptions相当于连接池的配置信息
MongoClientOptions build =
MongoClientOptions.builder().
writeConcern(WriteConcern.ACKNOWLEDGED).
codecRegistry(registry).build();
//ServerAddress serverAddress = new ServerAddress("localhost", 27017);
List<ServerAddress> asList =
Arrays.asList(new ServerAddress("localhost", 27018), new ServerAddress("localhost", 27017),
new ServerAddress("localhost", 27019));
client = new MongoClient(asList, build);
db = client.getDatabase("lison");
doc = db.getCollection("users", User.class);
}
插入数据
@Test
public void insertDemo() {
User user = new User();
user.setUsername("cang");
user.setCountry("USA");
user.setAge(20);
user.setLenght(1.77f);
user.setSalary(new BigDecimal("6265.22"));
//添加“address”子文档
Address address1 = new Address();
address1.setaCode("411222");
address1.setAdd("sdfsdf");
user.setAddress(address1);
//添加“favorites”子文档,其中两个属性是数组
Favorites favorites1 = new Favorites();
favorites1.setCites(Arrays.asList("东莞", "东京"));
favorites1.setMovies(Arrays.asList("西游记", "一路向西"));
user.setFavorites(favorites1);
User user1 = new User();
user1.setUsername("chen");
user1.setCountry("China");
user1.setAge(30);
user1.setLenght(1.77f);
user1.setSalary(new BigDecimal("6885.22"));
Address address2 = new Address();
address2.setaCode("411000");
address2.setAdd("我的地址2");
user1.setAddress(address2);
Favorites favorites2 = new Favorites();
favorites2.setCites(Arrays.asList("珠海", "东京"));
favorites2.setMovies(Arrays.asList("东游记", "一路向东"));
user1.setFavorites(favorites2);
//使用insertMany插入多条数据
doc.insertMany(Arrays.asList(user, user1));
}
查询数据: 和Document方式不同点仅仅只是返回的对象不同, Document返回的是通用的Document对象, pojo返回的是User
//文档集合
private MongoCollection<Document> doc; // 这个doc的collection可以带泛型, Document方式
private MongoCollection<User> doc; // User方式
@Test
public void testFind() {
final List<User> ret = new ArrayList<>();
Consumer<User> printDocument = new Consumer<User>() {
@Override
public void accept(User t) {
System.out.println(t.toString());
ret.add(t);
}
};
//select * from users where favorites.cites has "东莞"、"东京"
//db.users.find({ "favorites.cites" : { "$all" : [ "东莞" , "东京"]}})
Bson all = Filters.all("favorites.cites", Arrays.asList("东莞", "东京"));//定义数据过滤器,喜欢的城市中要包含"东莞"、"东京"
FindIterable<User> find = doc.find(all);
find.forEach(printDocument);
System.out.println("------------------>" + String.valueOf(ret.size()));
ret.removeAll(ret);
//select * from users where username like '%s%' and (contry= English or contry = USA)
// db.users.find({ "$and" : [ { "username" : { "$regex" : ".*c.*"}} , { "$or" : [ { "country" : "English"} , { "country" : "USA"}]}]})
String regexStr = ".*c.*";
Bson regex = Filters.regex("username", regexStr);//定义数据过滤器,username like '%s%'
Bson or = Filters.or(Filters.eq("country", "English"), Filters.eq("country", "USA"));//定义数据过滤器,(contry= English or contry = USA)
FindIterable<User> find2 = doc.find(Filters.and(regex, or));
find2.forEach(printDocument);
System.out.println("------------------>" + String.valueOf(ret.size()));
}
更新数据
@Test
public void testUpdate() {
//update users set age=6 where username = 'lison'
//db.users.updateMany({ "username" : "lison"},{ "$set" : { "age" : 6}},true)
Bson eq = Filters.eq("username", "lison");//定义数据过滤器,username = 'lison'
Bson set = Updates.set("age", 8);//更新的字段.来自于Updates包的静态导入
UpdateResult updateMany = doc.updateMany(eq, set);
System.out.println("------------------>" + String.valueOf(updateMany.getModifiedCount()));//打印受影响的行数
//update users set favorites.movies add "小电影2 ", "小电影3" where favorites.cites has "东莞"
//db.users.updateMany({ "favorites.cites" : "东莞"}, { "$addToSet" : { "favorites.movies" : { "$each" : [ "小电影2 " , "小电影3"]}}},true)
Bson eq2 = Filters.eq("favorites.cites", "东莞");//定义数据过滤器,favorites.cites has "东莞"
Bson addEachToSet = Updates.addEachToSet("favorites.movies", Arrays.asList("小电影2 ", "小电影3"));//更新的字段.来自于Updates包的静态导入
UpdateResult updateMany2 = doc.updateMany(eq2, addEachToSet);
System.out.println("------------------>" + String.valueOf(updateMany2.getModifiedCount()));
}
删除数据
@Test
public void testDelete() {
//delete from users where username = ‘lison’
//db.users.deleteMany({ "username" : "lison"} )
Bson eq = Filters.eq("username", "lison");//定义数据过滤器,username='lison'
DeleteResult deleteMany = doc.deleteMany(eq);
System.out.println("------------------>" + String.valueOf(deleteMany.getDeletedCount()));//打印受影响的行数
//delete from users where age >8 and age <25
//db.users.deleteMany({"$and" : [ {"age" : {"$gt": 8}} , {"age" : {"$lt" : 25}}]})
Bson gt = Filters.gt("age", 8);//定义数据过滤器,age > 8,所有过滤器的定义来自于Filter这个包的静态方法,需要频繁使用所以静态导入
Bson lt = Filters.lt("age", 25);//定义数据过滤器,age < 25
Bson and = Filters.and(gt, lt);//定义数据过滤器,将条件用and拼接
DeleteResult deleteMany2 = doc.deleteMany(and);
System.out.println("------------------>" + String.valueOf(deleteMany2.getDeletedCount()));//打印受影响的行数
}
两种方式的总结:
因为插入数据是插入一个文档, 所以Document方式传入的是一个Document, pojo方式是传入一个java bean
因为查询需要返回数据, 所以Document返回的是一个Document对象, pojo返回的是一个 java bean
因为更新和删除都没有文档传入和返回, 只有条件的封装和set封装, 所以都一样, 都是去封装bson
pom依赖坐标
<dependency>
<groupId>org.springframework.datagroupId>
<artifactId>spring-data-mongodbartifactId>
<version>2.2.1.RELEASEversion>
dependency>
applicationContext.xml创建bean
<mongo:mongo-client id="mongo" host="localhost" port="27017" credentials="lison:lison@lison"
replica-set="localhost:27017,localhost:27018,localhost:27019">
mongo:mongo-client>
<mongo:mongo-client id="mongo" host="localhost" port="27017">
<mongo:client-options
write-concern="ACKNOWLEDGED"
threads-allowed-to-block-for-connection-multiplier="5"
max-wait-time="1200"
connect-timeout="1000"/>
mongo:mongo-client>
<mongo:db-factory dbname="lison" mongo-ref="mongo"/>
<bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
<constructor-arg name="mongoConverter" ref="mappingConverter"/>
bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.data.mongodb.MongoTransactionManager">
<property name="dbFactory" ref="mongoDbFactory"/>
bean>
使用mongoTemplate
@Resource
private MongoOperations tempelate;
插入数据: 封装pojo
@Test
public void insertDemo() {
User user = new User();
user.setUsername("cang");
user.setCountry("USA");
user.setAge(20);
user.setLenght(1.77f);
user.setSalary(new BigDecimal("6265.22"));
//添加“address”子文档
Address address1 = new Address();
address1.setaCode("411222");
address1.setAdd("sdfsdf");
user.setAddress(address1);
//添加“favorites”子文档,其中两个属性是数组
Favorites favorites1 = new Favorites();
favorites1.setCites(Arrays.asList("东莞", "东京"));
favorites1.setMovies(Arrays.asList("西游记", "一路向西"));
user.setFavorites(favorites1);
User user1 = new User();
user1.setUsername("chen");
user1.setCountry("China");
user1.setAge(30);
user1.setLenght(1.77f);
user1.setSalary(new BigDecimal("6885.22"));
Address address2 = new Address();
address2.setaCode("411000");
address2.setAdd("我的地址2");
user1.setAddress(address2);
Favorites favorites2 = new Favorites();
favorites2.setCites(Arrays.asList("珠海", "东京"));
favorites2.setMovies(Arrays.asList("东游记", "一路向东"));
user1.setFavorites(favorites2);
tempelate.insertAll(Arrays.asList(user, user1));
}
查询: 返回pojo
@Test
public void testFind() {
//select * from users where favorites.cites has "东莞"、"东京"
//db.users.find({ "favorites.cites" : { "$all" : [ "东莞" , "东京"]}})
Criteria all = Criteria.where("favorites.cites").all(Arrays.asList("东莞", "东京"));
List<User> find = tempelate.find(Query.query(all), User.class);
System.out.println(find.size());
for (User user : find) {
System.out.println(user.toString());
}
//select * from users where username like '%s%' and (contry= English or contry = USA)
// db.users.find({ "$and" : [ { "username" : { "$regex" : ".*s.*"}} , { "$or" : [ { "country" : "English"} , { "country" : "USA"}]}]})
String regexStr = ".*c.*";
//username like '%s%'
Criteria regex = Criteria.where("username").regex(regexStr);
//contry= EngLish
Criteria or1 = Criteria.where("country").is("English");
//contry= USA
Criteria or2 = Criteria.where("country").is("USA");
Criteria or = new Criteria().orOperator(or1, or2);
Query query = Query.query(new Criteria().andOperator(regex, or));
List<User> find2 = tempelate.find(query, User.class);
System.out.println(find2.size());
for (User user : find2) {
System.out.println(user.toString());
}
}
更新: 就像是封装sql的where条件和set
@Test
public void testUpdate() {
//update users set age=6 where username = 'lison'
//db.users.updateMany({ "username" : "lison"},{ "$set" : { "age" : 6}},true)
Query query = Query.query(Criteria.where("username").is("lison"));
Update update = Update.update("age", 6);
UpdateResult updateFirst = tempelate.updateMulti(query, update, User.class);
System.out.println(updateFirst.getModifiedCount());
//update users set favorites.movies add "小电影2 ", "小电影3" where favorites.cites has "东莞"
//db.users.updateMany({ "favorites.cites" : "东莞"}, { "$addToSet" : { "favorites.movies" : { "$each" : [ "小电影2 " , "小电影3"]}}},true)
query = Query.query(Criteria.where("favorites.cites").is("东莞"));
update = new Update().addToSet("favorites.movies").each("小电影2 ", "小电影3");
UpdateResult updateMulti = tempelate.updateMulti(query, update, User.class);
System.out.println("--------------------->" + updateMulti.getModifiedCount());
}
删除: 封装where
@Test
public void testDelete() {
//delete from users where username = ‘lison’
//db.users.deleteMany({ "username" : "lison"} )
Query query = Query.query(Criteria.where("username").is("lison"));
DeleteResult remove = tempelate.remove(query, User.class);
System.out.println("--------------------->" + remove.getDeletedCount());
//delete from users where age >8 and age <25
//db.users.deleteMany({"$and" : [ {"age" : {"$gt": 8}} , {"age" : {"$lt" : 25}}]})
query = Query.query(new Criteria().andOperator(Criteria.where("age").gt(8), Criteria.where("age").lt(25)));
DeleteResult remove2 = tempelate.remove(query, User.class);
System.out.println("--------------------->" + remove2.getDeletedCount());
}
事务: 直接使用注解即可
@Transactional
public void doTransaction() {
Query query = query(where("username").is("lison"));
Update update = new Update().inc("lenght", 1);
tempelate.updateMulti(query, update, User.class);
query = query(where("username").is("james"));
update = new Update().inc("lenght", -1);
tempelate.updateMulti(query, update, User.class);
}
在 mongodb 3.4 版本里面新增了个数据类型 Decimal128, 但在前面操作的时候发现 User 里面的 salary 依然还是字符串
{
"_id": ObjectId("62e4b7c75173000062004e04"),
"username": "james",
"country": "English",
"address": {
"aCode": "311000",
"add": "地址"
},
"favorites": {
"movies": [
"复仇者联盟",
"战狼",
"雷神1"
],
"cites": [
"西安",
"东京",
"上海"
]
},
"age": 24,
"salary": "7889.09", // 这个使用的是字符串不是数字
"lenght": 1.35
}
我们可以使用类型转换器
Converter: 转换器
public class BigDecimalToDecimal128Converter implements Converter<BigDecimal, Decimal128> {
@Override
public Decimal128 convert(BigDecimal source) {
return new Decimal128(source);
}
}
public class Decimal128ToBigDecimalConverter implements Converter<Decimal128, BigDecimal> {
@Override
public BigDecimal convert(Decimal128 source) {
return source.bigDecimalValue();
}
}
<mongo:mapping-converter base-package="len.hgy.convert">
<mongo:custom-converters>
<mongo:converter>
<bean class="len.hgy.convert.BigDecimalToDecimal128Converter"/>
mongo:converter>
<mongo:converter>
<bean class="len.hgy.convert.Decimal128ToBigDecimalConverter"/>
mongo:converter>
mongo:custom-converters>
mongo:mapping-converter>
<bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
<constructor-arg name="mongoConverter" ref="mappingConverter"/>
bean>
// 1
{
"_id": ObjectId("62e4b7c75173000062004e04"),
"username": "james",
"country": "English",
"address": {
"aCode": "311000",
"add": "地址"
},
"favorites": {
"movies": [
"复仇者联盟",
"战狼",
"雷神1"
],
"cites": [
"西安",
"东京",
"上海"
]
},
"age": 24,
"salary": NumberDecimal("7889.09"),
"lenght": 1.35
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NhXDIg9E-1660461785665)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207312311269.png)]
可见 mongodb 具备强大的向下兼容性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N3Kg2qlD-1660461785666)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207312312578.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Esqm3TVN-1660461785667)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207312312226.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wpKrvFN1-1660461785668)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202207312314588.png)]
db.collection.find(query, projection);
db.users.find({"$and":[{"username":"lison"},{"age":18}]},{"username":0,"age":0})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCQKUXbc-1660461785669)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202208012355831.png)]
db.users.find({"username":{"$in":["lison","mark"]}}).pretty();
db.users.find({"$or":[{"username":"lison"},{"username":"mark"}]});
// 判断文档有没有关心的字段
db.users.find({"length":{"$exists":true}}).pretty();
// not 语句 会把不包含查询语句字段的文档 也检索出来
db.users.find({"length":{"$not":{"$gte":1.77}}}).pretty();
db.users.find({"$or":[{"length":{"$lt":1.77}},{"length":{"$exists":false}}]}).pretty();
db.users.find({},{"username":1});
db.users.find({},{"username":1, "age":1});
// 映射的value值必须是相同的, 意思就是如果选择使用排除法就使用排除法, 如果使用选择法就使用选择法, 不然会混乱的
db.users.find({},{"username":0});
// 1: 升序, -1: 降序, 理解成 +1 和 -1
db.users.find().sort({"username":1}).pretty();
skip(n): 跳过n条数据
limit(n): 限制n条数据
db.users.find().sort({"username":1}).limit(2).skip(2);
查询唯一值
distinct(): 查询字段的唯一值
// 这参数竟然不是json形式的入参
db.users.distinct("username");
db.users.find({"favorites.movies":"流浪地球"})
// 查询数组 严格按照数量、顺序相等
db.users.find({"favorites.movies":["战神", "雷神","不死鸟"]}, {"favorites.movies":1})
// 内容数量相等, 和顺序无关
db.users.find({"favorites.movies":{"$all":["雷神1", "天堂"]}})
// 内容包含, 和数据顺序无关
db.users.find({"favorites.movies":{"$in":["雷神1", "天堂"]}})
// 数组的第一个索引位置
db.users.find({"favorites.movies.0":"鬼吹灯",{"favorites.movies":1}})
// $slice 可以取两个元素数组, 分别表示跳过和限制条数
db.users.find({}, {"favorites.movies":{"$slice":[1,2]}, "favorites":1})
// 可以和下面结果对比
db.users.find({},{"favorites":1})
// 说明: comments是一个数组
db.users.find({"comments":{"author":"lison6", "context": "xxx"}, "commentTime": ISODate("2017-06-06T00:00:00Z")})
// 备注:跟数量无关,跟顺序无关;
db.users.find({"comments.author":{"$in":["lison1", "lison2"]}})
// 备注:跟数量有关,跟顺序无关;
db.users.find({"comments.author":{"$all":["lison12","lison1"]}}).pretty()
// 备注:数组中对象数据要符合查询对象里面所有的字段,全元素匹配,和顺序无关;
// $elemMatch: 匹配么一个元素
db.users.find({"comments":{"$elemMatch":{"author":"lison5", "content":{"$regex":".*早上好.*"}}}})
// 静态导入
import static com.mongodb.client.model.Aggregates.*;
import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Projections.*;
import static com.mongodb.client.model.Sorts.ascending;
import static com.mongodb.client.model.Sorts.orderBy;
private MongoDatabase db;
private MongoCollection<Document> collection;
private MongoCollection<Document> orderCollection;
@Resource(name = "mongo")
private MongoClient client;
@Before
public void init() {
db = client.getDatabase("lison");
collection = db.getCollection("users");
orderCollection = db.getCollection("ordersTest");
}
in
// db.users.find({"username":{"$in":["lison", "mark", "james"]}}).pretty()
// 查询姓名为lison、mark和james这个范围的人
@Test
public void testInOper() {
Bson in = in("username", "lison", "mark", "james");
FindIterable<Document> find = collection.find(in);
printOperation(find);
}
exists
// db.users.find({"lenght":{"$exists":true}}).pretty()
// 判断文档有没有关心的字段
@Test
public void testExistsOper() {
Bson exists = exists("lenght", true);
FindIterable<Document> find = collection.find(exists);
printOperation(find);
}
sort, limit, skip
// db.users.find().sort({"username":1}).limit(1).skip(2)
// 测试sort,limit,skip
@Test
public void testSLSOper() {
Document sort = new Document("username", 1);
FindIterable<Document> find = collection.find().sort(sort).limit(1).skip(2);
printOperation(find);
}
not,gte
// db.users.find({"lenght":{"$not":{"$gte":1.77}}}).pretty()
// 查询高度小于1.77或者没有身高的人
// not语句 会把不包含查询语句字段的文档 也检索出来
@Test
public void testNotOper() {
Bson gte = gte("lenght", 1.77);
Bson not = not(gte);
FindIterable<Document> find = collection.find(not);
printOperation(find);
}
字符串数组
// db.users.find({"favorites.movies":"蜘蛛侠"})
// 查询数组中包含"蜘蛛侠"
@Test
public void testArray1() {
Bson eq = eq("favorites.movies", "蜘蛛侠");
FindIterable<Document> find = collection.find(eq);
printOperation(find);
}
// db.users.find({"favorites.movies":[ "妇联4","杀破狼2", "战狼", "雷神1","神奇动物在哪里"]},{"favorites.movies":1})
// 查询数组等于[ “杀破狼2”, “战狼”, “雷神1” ]的文档,严格按照数量、顺序;
@Test
public void testArray2() {
Bson eq = eq("favorites.movies", Arrays.asList("妇联4", "杀破狼2", "战狼", "雷神1", "神奇动物在哪里"));
FindIterable<Document> find = collection.find(eq);
printOperation(find);
}
//数组多元素查询
@Test
public void testArray3() {
// db.users.find({"favorites.movies":{"$all":[ "雷神1", "战狼"]}},{"favorites.movies":1})
// 查询数组包含["雷神1", "战狼" ]的文档,跟顺序无关
Bson all = all("favorites.movies", Arrays.asList("雷神1", "战狼"));
FindIterable<Document> find = collection.find(all);
printOperation(find);
// db.users.find({"favorites.movies":{"$in":[ "雷神1", "战狼" ]}},{"favorites.movies":1})
// 查询数组包含[“雷神1”, “战狼” ]中任意一个的文档,跟顺序无关,跟数量无关
Bson in = in("favorites.movies", Arrays.asList("雷神1", "战狼"));
find = collection.find(in);
printOperation(find);
}
// // db.users.find({"favorites.movies.0":"妇联4"},{"favorites.movies":1})
// 查询数组中第一个为"妇联4"的文档
@Test
public void testArray4() {
Bson eq = eq("favorites.movies.0", "妇联4");
FindIterable<Document> find = collection.find(eq);
printOperation(find);
}
// db.users.find({},{"favorites.movies":{"$slice":[1,2]},"favorites":1})
// $slice可以取两个元素数组,分别表示跳过和限制的条数;
@Test
public void testArray5() {
Bson slice = slice("favorites.movies", 1, 2);
Bson include = include("favorites");
Bson projection = fields(slice, include);
FindIterable<Document> find = collection.find().projection(projection);
printOperation(find);
}
对象数组查询实例
//db.users.find({"comments":{"author":"lison6","content":"lison评论6","commentTime":ISODate("2017-06-06T00:00:00Z")}})
//备注:对象数组精确查找
@Test
public void testObjArray1() throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2017-06-06 08:00:00");
Document comment =
new Document().append("author", "lison6").append("content", "lison评论6").append("commentTime", commentDate);
Bson eq = eq("comments", comment);
FindIterable<Document> find = collection.find(eq);
printOperation(find);
}
//数组多元素查询
@Test
public void testObjArray2() {
// 查找lison1 或者 lison12评论过的user ($in查找符)
// db.users.find({"comments.author":{"$in":["lison1","lison12"]}}).pretty()
// 备注:跟数量无关,跟顺序无关;
Bson in = in("comments.author", Arrays.asList("lison1", "lison12"));
FindIterable<Document> find = collection.find(in);
printOperation(find);
// 查找lison1 和 lison12都评论过的user
// db.users.find({"comments.author":{"$all":["lison12","lison1"]}}).pretty()
// 备注:跟数量有关,跟顺序无关;
Bson all = all("comments.author", Arrays.asList("lison12", "lison1"));
find = collection.find(all);
printOperation(find);
}
//查找lison5评语为包含“苍老师”关键字的user($elemMatch查找符)
// db.users.find({"comments":{"$elemMatch":{"author" : "lison5", "content" : { "$regex" : ".*苍老师.*"}}}})
//备注:数组中对象数据要符合查询对象里面所有的字段,$全元素匹配,和顺序无关;
@Test
public void testObjArray3() throws ParseException {
Bson eq = eq("author", "lison5");
Bson regex = regex("content", ".*苍老师.*");
Bson elemMatch = Filters.elemMatch("comments", and(eq, regex));
FindIterable<Document> find = collection.find(elemMatch);
printOperation(find);
}
聚合操作
/**
* db.orders.aggregate([
* {"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
* {"$group":{"_id":{"useCode":"$useCode","month":{"$month":"$orderTime"}},"total":{"$sum":"$price"}}},
* {"$sort":{"_id":1}}
* ])
*/
@Test
public void aggretionTest1() throws Exception {
Block<Document> printBlock = new Block<Document>() {
@Override
public void apply(Document t) {
logger.info("---------------------");
System.out.println(t.toJson());
logger.info("---------------------");
}
};
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2015-04-03 08:00:00");
DBObject groupFileds = new BasicDBObject();
groupFileds.put("useCode", "$useCode");
groupFileds.put("month", eq("$month", "$orderTime"));
List<Bson> aggregates = new ArrayList<Bson>();
aggregates.add(match(lt("orderTime", commentDate)));
aggregates.add(group(groupFileds, Accumulators.sum("sum", "$price")));
aggregates.add(sort(eq("_id", 1)));
AggregateIterable<Document> aggregate = orderCollection.aggregate(aggregates);
aggregate.forEach(printBlock);
}
/**
* db.orders.aggregate([{"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
* {"$unwind":"$Auditors"},
* {"$group":{"_id":{"Auditors":"$Auditors"},"total":{"$sum":"$price"}}},
* {"$sort":{"_id":1}}])
*/
@Test
public void aggretionTest2() throws Exception {
Block<Document> printBlock = new Block<Document>() {
@Override
public void apply(Document t) {
logger.info("---------------------");
System.out.println(t.toJson());
logger.info("---------------------");
}
};
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2015-04-03 08:00:00");
List<Bson> aggregates = new ArrayList<Bson>();
aggregates.add(match(lt("orderTime", commentDate)));
aggregates.add(unwind("$Auditors"));
aggregates.add(group("$Auditors", Accumulators.sum("sum", "$price")));
aggregates.add(sort(eq("_id", 1)));
AggregateIterable<Document> aggregate = orderCollection.aggregate(aggregates);
aggregate.forEach(printBlock);
}
demo实例
/ 新增评论时,使用$sort运算符进行排序,插入评论后,再按照评论时间降序排序
public void demoStep1() {
Bson filter = eq("username", "lison");
Document comment =
new Document().append("author", "cang").append("content", "lison是我的粉丝").append("commentTime", new Date());
// $sort: {"commentTime":-1}
Document sortDoc = new Document().append("commentTime", -1);
PushOptions sortDocument = new PushOptions().sortDocument(sortDoc);
// $each
Bson pushEach = Updates.pushEach("comments", Arrays.asList(comment), sortDocument);
UpdateResult updateOne = collection.updateOne(filter, pushEach);
System.out.println(updateOne.getModifiedCount());
}
@Test
// 查看人员时加载最新的三条评论;
// db.users.find({"username":"lison"},{"comments":{"$slice":[0,3]}}).pretty()
public void demoStep2() {
FindIterable<Document> find = collection.find(eq("username", "lison")).projection(slice("comments", 0, 3));
printOperation(find);
}
@Test
// 点击评论的下一页按钮,新加载三条评论
// db.users.find({"username":"lison"},{"comments":{"$slice":[3,3]},"$id":1}).pretty();
public void demoStep3() {
// {"username":"lison"}
Bson filter = eq("username", "lison");
// "$slice":[3,3]
Bson slice = slice("comments", 3, 3);
// "$id":1
Bson includeID = include("id");
// {"comments":{"$slice":[3,3]},"$id":1})
Bson projection = fields(slice, includeID);
FindIterable<Document> find = collection.find(filter).projection(projection);
printOperation(find);
}
@Test
/**
* db.users.aggregate([{"$match":{"username":"lison"}},
{"$unwind":"$comments"},
{$sort:{"comments.commentTime":-1}},
{"$project":{"comments":1}},
{"$skip":6},
{"$limit":3}])
*/
// 如果有多种排序需求怎么处理,使用聚合
public void demoStep4() {
final List<Document> ret = new ArrayList<Document>();
Block<Document> printBlock = getBlock(ret);
List<Bson> aggregates = new ArrayList<Bson>();
aggregates.add(match(eq("username", "lison")));
aggregates.add(unwind("$comments"));
aggregates.add(sort(orderBy(ascending("comments.commentTime"))));
aggregates.add(project(fields(include("comments"))));
aggregates.add(skip(0));
aggregates.add(limit(3));
AggregateIterable<Document> aggregate = collection.aggregate(aggregates);
printOperation(ret, printBlock, aggregate);
}
依赖
<dependency>
<groupId>org.springframework.datagroupId>
<artifactId>spring-data-mongodbartifactId>
<version>2.2.1.RELEASEversion>
dependency>
配置文件: applicationContext.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<context:component-scan base-package="len.hgy">
context:component-scan>
<mongo:mongo-client id="mongo" host="localhost" port="27017" credentials="lison:lison@lison"
replica-set="localhost:27017,localhost:27018,localhost:27019">
mongo:mongo-client>
<mongo:mongo-client id="mongo" host="localhost" port="27017">
<mongo:client-options
write-concern="ACKNOWLEDGED"
threads-allowed-to-block-for-connection-multiplier="5"
max-wait-time="1200"
connect-timeout="1000"/>
mongo:mongo-client>
<mongo:db-factory dbname="lison" mongo-ref="mongo"/>
<bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
<constructor-arg name="mongoConverter" ref="mappingConverter"/>
bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.data.mongodb.MongoTransactionManager">
<property name="dbFactory" ref="mongoDbFactory"/>
bean>
<mongo:mapping-converter base-package="len.hgy.convert">
<mongo:custom-converters>
<mongo:converter>
<bean class="len.hgy.convert.BigDecimalToDecimal128Converter"/>
mongo:converter>
<mongo:converter>
<bean class="len.hgy.convert.Decimal128ToBigDecimalConverter"/>
mongo:converter>
mongo:custom-converters>
mongo:mapping-converter>
beans>
测试用例
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringQueryTest {
private static final Logger logger = LoggerFactory.getLogger(SpringQueryTest.class);
@Resource
private MongoOperations tempelate;
// -----------------------------操作符使用实例------------------------------------------
// db.users.find({"username":{"$in":["lison", "mark", "james"]}}).pretty()
// 查询姓名为lison、mark和james这个范围的人
@Test
public void testInOper() {
Query query = query(where("username").in("lison", "mark", "james"));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
// db.users.find({"lenght":{"$exists":true}}).pretty()
// 判断文档有没有关心的字段
@Test
public void testExistsOper() {
Query query = query(where("lenght").exists(true));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
// db.users.find().sort({"username":1}).limit(1).skip(2)
// 测试sort,limit,skip
@Test
public void testSLSOper() {
//Query query = query(where(null)).with(new Sort(new Sort.Order(Direction.ASC, "username"))).limit(1).skip(2);
Query query = query(where(null)).with(Sort.by(Direction.ASC, "username")).limit(1).skip(2);
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
// db.users.find({"lenght":{"$not":{"$gte":1.77}}}).pretty()
// 查询高度小于1.77或者没有身高的人
// not语句 会把不包含查询语句字段的文档 也检索出来
@Test
public void testNotOper() {
Query query = query(where("lenght").not().gte(1.77));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
// -----------------------------字符串数组查询实例------------------------------------------
// db.users.find({"favorites.movies":"蜘蛛侠"})
// 查询数组中包含"蜘蛛侠"
@Test
public void testArray1() {
Query query = query(where("favorites.movies").is("蜘蛛侠"));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
// db.users.find({"favorites.movies":[ "妇联4","杀破狼2", "战狼", "雷神1","神奇动物在哪里"]},{"favorites.movies":1})
// 查询数组等于[ “杀破狼2”, “战狼”, “雷神1” ]的文档,严格按照数量、顺序;
@Test
public void testArray2() {
Query query = query(where("favorites.movies").is(Arrays.asList("妇联4", "杀破狼2", "战狼", "雷神1", "神奇动物在哪里")));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
//数组多元素查询
@Test
public void testArray3() {
// db.users.find({"favorites.movies":{"$all":[ "雷神1", "战狼"]}},{"favorites.movies":1})
// 查询数组包含["雷神1", "战狼" ]的文档,跟顺序无关
Query query = query(where("favorites.movies").all(Arrays.asList("雷神1", "战狼")));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
// db.users.find({"favorites.movies":{"$in":[ "雷神1", "战狼" ]}},{"favorites.movies":1})
// 查询数组包含[“雷神1”, “战狼” ]中任意一个的文档,跟顺序无关,跟数量无关
query = query(where("favorites.movies").in(Arrays.asList("雷神1", "战狼")));
find = tempelate.find(query, User.class);
printUsers(find);
}
// // db.users.find({"favorites.movies.0":"妇联4"},{"favorites.movies":1})
// 查询数组中第一个为"妇联4"的文档
@Test
public void testArray4() {
Query query = query(where("favorites.movies.0").is("妇联4"));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
// db.users.find({},{"favorites.movies":{"$slice":[1,2]},"favorites":1})
// $slice可以取两个元素数组,分别表示跳过和限制的条数;
@Test
public void testArray5() {
Query query = query(where(null));
query.fields().include("favorites").slice("favorites.movies", 1, 2);
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
// -----------------------------对象数组查询实例------------------------------------------
//db.users.find({"comments":{"author":"lison6","content":"lison评论6","commentTime":ISODate("2017-06-06T00:00:00Z")}})
//备注:对象数组精确查找
//坑:居然和属性定义的顺序有关
@Test
public void testObjArray1() throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2017-06-06 08:00:00");
Comment comment = new Comment();
comment.setAuthor("lison6");
comment.setCommentTime(commentDate);
comment.setContent("lison评论6");
Query query = query(where("comments").is(comment));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
//数组多元素查询
@Test
public void testObjArray2() {
// 查找lison1 或者 lison12评论过的user ($in查找符)
// db.users.find({"comments.author":{"$in":["lison1","lison12"]}}).pretty()
// 备注:跟数量无关,跟顺序无关;
Query query = query(where("comments.author").in(Arrays.asList("lison1", "lison12")));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
// 查找lison1 和 lison12都评论过的user
// db.users.find({"comments.author":{"$all":["lison12","lison1"]}}).pretty()
// 备注:跟数量有关,跟顺序无关;
query = query(where("comments.author").all(Arrays.asList("lison1", "lison12")));
find = tempelate.find(query, User.class);
printUsers(find);
}
@Test
//(1)注意相关的实体bean要加上注解@document,@dbRef
//(2)spring对dbRef进行了封装,发起了两次查询请求
public void dbRefTest() {
System.out.println("----------------------------");
List<User> users = tempelate.findAll(User.class);
System.out.println("----------------------------");
System.out.println(users);
// System.out.println(users.get(0).getComments());
}
private void printUsers(List<User> find) {
for (User user : find) {
System.out.println(user);
}
System.out.println(find.size());
}
//---------------------------------------------------------
//查找lison5评语为包含“苍老师”关键字的user($elemMatch查找符)
// db.users.find({"comments":{"$elemMatch":{"author" : "lison5", "content" : { "$regex" : ".*苍老师.*"}}}})
//备注:数组中对象数据要符合查询对象里面所有的字段,$全元素匹配,和顺序无关;
@Test
public void testObjArray3() throws ParseException {
// and(where("author").is("lison5"),where("content").regex(".*苍老师.*")))
Criteria andOperator =
new Criteria().andOperator(where("author").is("lison5"), where("content").regex(".*苍老师.*"));
Query query = query(where("comments").elemMatch(andOperator));
List<User> find = tempelate.find(query, User.class);
printUsers(find);
}
/**
* db.orders.aggregate([
* {"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
* {"$group":{"_id":{"useCode":"$useCode","month":{"$month":"$orderTime"}},"total":{"$sum":"$price"}}},
* {"$sort":{"_id":1}}
* ])
*/
@Test
public void aggretionTest1() throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2015-04-04 00:00:00");
Aggregation aggs = newAggregation(match(where("orderTime").lt(commentDate)),
project("useCode", "price", "orderTime").and(DateOperators.DateToString.dateOf("orderTime").toString("%m"))
.as("month"), group("useCode", "month").sum("price").as("total"), sort(Sort.by(Direction.ASC, "_id")));
AggregationResults<Object> aggregate = tempelate.aggregate(aggs, "orders", Object.class);
List<Object> mappedResults = aggregate.getMappedResults();
System.out.println(mappedResults);
}
/**
* db.orders.aggregate([{"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
* {"$unwind":"$Auditors"},
* {"$group":{"_id":{"Auditors":"$Auditors"},"total":{"$sum":"$price"}}},
* {"$sort":{"_id":1}}])
*/
@Test
public void aggretionTest2() throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2015-04-04 00:00:00");
Aggregation aggs = newAggregation(match(where("orderTime").lt(commentDate)), unwind("Auditors"),
group("Auditors").sum("price").as("total"), sort(Sort.by(Direction.ASC, "_id")));
AggregationResults<Object> aggregate = tempelate.aggregate(aggs, "orders", Object.class);
List<Object> mappedResults = aggregate.getMappedResults();
System.out.println(mappedResults);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ztggLtqk-1660461785671)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202208040157522.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xG5tOP15-1660461785672)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202208040157401.png)]
单个 bson 文档最大不能超过 16M;当文档超过 16M 的时候,就应该考虑使用引用 (DBRef)了,在主表里存储一个 id 值,指向另一个表中的 id 值。
DBRef 语法:{ “
r
e
f
"
:
<
v
a
l
u
e
>
,
"
ref" :
$ref:引用文档所在的集合的名称;
$id:所在集合的_id 字段值;
$db:可选,集合所在的数据库实例;
Tips:DBRef 只是关联信息的数据载体,本身并不会去关联数据
dbref 脚本示例
var lison = db.users.findOne({"username":"lison"});
var dbref = lison.comments;
db[dbref.$ref].findOne({"_id":dbref.$id})
创建一个数据
// 原始数据
{
"_id": ObjectId("62f7ceef4c3000002e005562"),
"username": "lison",
"address": {
"aCode": "411000",
"add": "长沙"
},
"favorites": {
"movies": [
"杀破狼2",
"战狼",
"雷神1"
],
"cites": [
"长沙",
"深圳",
"上海"
]
},
"salary": NumberDecimal("18889.09"),
"length": 1.79
}
db.users.findOne({"username":"lison"})
db.users.insert({
"username": "dbref",
"comments": {
// 三个字段必须具有这个顺序, 因为查询出来的顺序就是这样的: 集合, id, 数据库, 如果是同一个数据库可以省略
// "comments": DBRef("users", ObjectId("62f7ceef4c3000002e005562"), "mgdb")
"$ref": "users",
"$id": ObjectId("62f7ceef4c3000002e005562"),
"$db": "mgdb"
}
})
db.users.findOne({"username":"dbref"})
// 1
{
"_id": ObjectId("62f7dcb04c3000002e005568"),
"username": "dbref",
"comments": DBRef("users", ObjectId("62f7ceef4c3000002e005562"), "mgdb")
}
// 省略$db
db.users.insert({
"username": "dbref2",
"comments": {
"$ref": "users",
"$id": ObjectId("62f7ceef4c3000002e005562")
}
})
// 1
{
"_id": ObjectId("62f7dd3f4c3000002e005569"),
"username": "dbref2",
"comments": DBRef("users", ObjectId("62f7ceef4c3000002e005562"))
}
查询
var dbref1 = db.users.findOne({"username":"dbref"});
var dbref = dbref1.comments;
// dbref.$ref就是应用的文档, dbref.$id 就是稳定的id
db[dbref.$ref].findOne({"_id":dbref.$id})
// 1 通过username=dbref关联查询出lison的数据
{
"_id": ObjectId("62f7ceef4c3000002e005562"),
"username": "lison",
"address": {
"aCode": "411000",
"add": "长沙"
},
"favorites": {
"movies": [
"杀破狼2",
"战狼",
"雷神1"
],
"cites": [
"长沙",
"深圳",
"上海"
]
},
"salary": NumberDecimal("18889.09"),
"length": 1.79
}
JAVA 客户端解析
// dbRef测试
// dbref其实就是关联关系的信息载体,本身并不会去关联数据
@Test
public void dbRefTest() {
FindIterable<Document> find = collection.find(eq("username", "lison"));
printOperation(find);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QicT7T0z-1660461785673)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202208040207054.png)]
Spring data mongo 解析
@Test
//(1)注意相关的实体bean要加上注解@document,@dbRef
//(2)spring对dbRef进行了封装,发起了两次查询请求
public void dbRefTest() {
System.out.println("----------------------------");
List<User> users = tempelate.findAll(User.class);
System.out.println("----------------------------");
System.out.println(users);
// System.out.println(users.get(0).getComments());
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ccNdtFLX-1660461785673)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202208040209014.png)]
聚合框架就是定义一个管道,管道里的每一步都为下一步输出数据数据 (类似于 JDK8 的 Stream API,既流式编程)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yXvE6o8u-1660461785674)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202208040210408.png)]
$group 操作符
$group:可以分组的数据执行如下的表达式计算:
$sum:计算总和。
$avg:计算平均值。
$min:根据分组,获取集合中所有文档对应值得最小值。
$max:根据分组,获取集合中所有文档对应值得最大值。
@Document(collection = "orders")
public class Order {
@Id
private String id;
private String orderCode;
private String useCode;
private Date orderTime;
private BigDecimal price;
private String[] Auditors;
}
public class RondomDateTest {
/**
* 获取随机日期
*
* @param beginDate 起始日期,格式为:yyyy-MM-dd
* @param endDate 结束日期,格式为:yyyy-MM-dd
* @return
*/
public static Date randomDate(String beginDate, String endDate) {
try {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date start = format.parse(beginDate);
Date end = format.parse(endDate);
if (start.getTime() >= end.getTime()) {
return null;
}
long date = random(start.getTime(), end.getTime());
return new Date(date);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static long random(long begin, long end) {
long rtn = begin + (long)(Math.random() * (end - begin));
if (rtn == begin || rtn == end) {
return random(begin, end);
}
return rtn;
}
public static BigDecimal randomBigDecimal(float max, float min) {
// float Max = 10000, Min = 1.0f;
BigDecimal db = new BigDecimal(Math.random() * (max - min) + min);
return db.setScale(2, BigDecimal.ROUND_HALF_UP);// 保留30位小数并四舍五入
}
@Test
public void testRondomDate() {
for (int i = 0; i <= 10000; i++) {
// Date date = randomDate("2015-01-01","2017-10-31");
// System.out.println(new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(date));
BigDecimal test = randomBigDecimal(10000, 1);
System.out.println(test.toString());
}
}
}
使用 GenarateOrdersTest 产生 100000 条测试数据,代码如下
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class GenarateOrdersTest {
private static final Logger logger = LoggerFactory.getLogger(GenarateOrdersTest.class);
@Resource
private MongoOperations tempelate;
//随机生成orderTest数据
@Test
public void batchInsertOrder() {
String[] userCodes =
new String[] {"james", "AV", "allen", "six", "peter", "mark", "king", "zero", "lance", "deer", "lison"};
String[] auditors = new String[] {"auditor1", "auditor2", "auditor3", "auditor4", "auditor5"};
List<Order> list = new ArrayList<Order>();
Random rand = new Random();
for (int i = 0; i < 1000; i++) {
Order order = new Order();
int num = rand.nextInt(11);
order.setUseCode(userCodes[num]);
order.setOrderCode(UUID.randomUUID().toString());
order.setOrderTime(RondomDateTest.randomDate("2015-01-01", "2017-10-31"));
order.setPrice(RondomDateTest.randomBigDecimal(10000, 1));
int length = rand.nextInt(5) + 1;
String[] temp = new String[length];
for (int j = 0; j < temp.length; j++) {
temp[j] = getFromArrays(temp, auditors, rand);
}
order.setAuditors(temp);
list.add(order);
}
tempelate.insertAll(list);
}
private String getFromArrays(String[] temp, String[] auditors, Random rand) {
String ret = null;
boolean test = true;
while (test) {
ret = auditors[rand.nextInt(5)];
int i = 0;
for (String _temp : temp) {
i++;
if (ret.equals(_temp)) {
break;
}
}
if (i == temp.length) {
test = false;
}
}
return ret;
}
}
db.orders.aggregate([
{
"$match": {
"orderTime": {
"$lt": new Date("2015-04-03T16:00:00.000Z")
}
}
},
{
"$group": {
// 第一个key是分组
"_id": { // 这个是重命名
"useCode": "$useCode",
"month": { // 这个也是对日志操作后的重名命名
// 这里的month是一个函数操作, 也可以改成$year
// $xx, 在:右边就是字段, 在:左边就是内置函数操作
"$month": "$orderTime"
}
},
// 后面的key都是分组的计算结果
"total": {
"$sum": "$price"
},
"avg": {
"$avg" : "$price"
}
}
},
{
"$sort": {
"_id": 1
}
}
]);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ayhgMHaK-1660461785674)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202208131907003.png)]
db.orders.aggregate([
{
"$match": {
"orderTime": {
"$lt": new Date("2015-04-03T00:00:00.000Z")
}
}
},
{
"$unwind": "$Auditors"
},
{
"$group": {
"_id": {
"Auditors": "$Auditors"
},
"total": {
"$sum": "$price"
}
}
},
{
"$sort": {
"_id": 1
}
}
]);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PUMQJSuF-1660461785675)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202208131909481.png)]
// 静态导入
import static com.mongodb.client.model.Aggregates.*;
import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Projections.*;
import static com.mongodb.client.model.Sorts.ascending;
import static com.mongodb.client.model.Sorts.orderBy;
/**
* db.orders.aggregate([
* {"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
* {"$group":{"_id":{"useCode":"$useCode","month":{"$month":"$orderTime"}},"total":{"$sum":"$price"}}},
* {"$sort":{"_id":1}}
* ])
*/
@Test
public void aggretionTest1() throws Exception {
Block<Document> printBlock = new Block<Document>() {
@Override
public void apply(Document t) {
logger.info("---------------------");
System.out.println(t.toJson());
logger.info("---------------------");
}
};
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2015-04-03 08:00:00");
DBObject groupFileds = new BasicDBObject();
groupFileds.put("useCode", "$useCode");
// 这种函数操作字段的直接使用eq连接即可, 所以只要是冒号连接的都可以直接使用eq
groupFileds.put("month", eq("$month", "$orderTime"));
List<Bson> aggregates = new ArrayList<Bson>();
aggregates.add(match(lt("orderTime", commentDate)));
// 有专门的group方法, , 但是sum没有使用专门的方法
aggregates.add(group(groupFileds, Accumulators.sum("sum", "$price")));
// 有专门的sort方法
aggregates.add(sort(eq("_id", 1)));
AggregateIterable<Document> aggregate = orderCollection.aggregate(aggregates);
aggregate.forEach(printBlock);
}
/**
* db.orders.aggregate([{"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
* {"$unwind":"$Auditors"},
* {"$group":{"_id":{"Auditors":"$Auditors"},"total":{"$sum":"$price"}}},
* {"$sort":{"_id":1}}])
*/
@Test
public void aggretionTest2() throws Exception {
Block<Document> printBlock = new Block<Document>() {
@Override
public void apply(Document t) {
logger.info("---------------------");
System.out.println(t.toJson());
logger.info("---------------------");
}
};
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2015-04-03 08:00:00");
List<Bson> aggregates = new ArrayList<Bson>();
// 都有专门的函数, 但是sum没有使用专门的方法
aggregates.add(match(lt("orderTime", commentDate)));
aggregates.add(unwind("$Auditors"));
aggregates.add(group("$Auditors", Accumulators.sum("sum", "$price")));
aggregates.add(sort(eq("_id", 1)));
AggregateIterable<Document> aggregate = orderCollection.aggregate(aggregates);
aggregate.forEach(printBlock);
}
// 静态导入
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
/**
* db.orders.aggregate([
* {"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
* {"$group":{"_id":{"useCode":"$useCode","month":{"$month":"$orderTime"}},"total":{"$sum":"$price"}}},
* {"$sort":{"_id":1}}
* ])
*/
@Test
public void aggretionTest1() throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2015-04-04 00:00:00");
Aggregation aggs = newAggregation(match(where("orderTime").lt(commentDate)),
project("useCode", "price", "orderTime").and(DateOperators.DateToString.dateOf("orderTime").toString("%m"))
.as("month"), group("useCode", "month").sum("price").as("total"), sort(Sort.by(Direction.ASC, "_id")));
AggregationResults<Object> aggregate = tempelate.aggregate(aggs, "orders", Object.class);
List<Object> mappedResults = aggregate.getMappedResults();
System.out.println(mappedResults);
}
/**
* db.orders.aggregate([{"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
* {"$unwind":"$Auditors"},
* {"$group":{"_id":{"Auditors":"$Auditors"},"total":{"$sum":"$price"}}},
* {"$sort":{"_id":1}}])
*/
@Test
public void aggretionTest2() throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date commentDate = formatter.parse("2015-04-04 00:00:00");
Aggregation aggs = newAggregation(match(where("orderTime").lt(commentDate)), unwind("Auditors"),
group("Auditors").sum("price").as("total"), sort(Sort.by(Direction.ASC, "_id")));
AggregationResults<Object> aggregate = tempelate.aggregate(aggs, "orders", Object.class);
List<Object> mappedResults = aggregate.getMappedResults();
System.out.println(mappedResults);
}
insertOne:插入单个文档
insertMany:插入多个文档
如果数据库和集合不存在,insert 操作将自动创建;
对于插入的数据,mongoDB 自动生成 ObjectId 作为_id 字段(物理主键)
deleteOne(query):删除单个文档
deleteMany(query):删除多个文档
删除操作是不会删除索引的,就算你把数据全部删除;
替换更新
db.users.find({"username":"lison"})
db.users.update({"username":"lison"}, {"country":"USA"}) // 替换更新, 会把除了id和第二个参数没有指定的字段全部删除
db.users.find( {"country":"USA"})
// 1
{
"_id": ObjectId("62e803f2597c0000a60068c2"),
"country": "USA"
}
操作符更新 (推荐使用)
性能更好
原子性操作
db.users.update({"username":"james"},{"$set":{"country":"USA"}})
修改语法
db.collection.update(
<query>,
<update>,
{ upsert: <boolean>, multi: <boolean>, writeConcern: <document> }
)
参数说明
示例
db.users.update({"username":"cang"},{"$set":{"age":18}},{"upsert":true})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rlyLoIsz-1660461785676)(https://fbed-1303888495.cos.ap-guangzhou.myqcloud.com/typora/202208140015300.png)]
删除字段示例
这里如果使用 s e t 指定为空串就会变成空串 , 但是使用 set指定为空串就会变成空串, 但是使用 set指定为空串就会变成空串,但是使用unset指定为空串就会变成删除这个字段
db.users.updateMany({"username":"lison"},{"$unset":{"country":"","age":""}})
更新字段名称示例
db.users.updateMany({"username":"lison"},{"$rename":{"lenght":"height", "username":"name"}})
$each 作用示例
将一个数组打散, 放入数组中, 而不是把整个数组当作一个数据放入数组中–拉平
db.users.updateMany({ "username" : "james"}, { "$addToSet" : { "favorites.movies" : [ "小电影 2 " , "小电影 3"]}})
db.users.updateMany({ "username" : "james"}, { "$addToSet" : { "favorites.movies" : { "$each" : [ "小电影 2 " , "小电影 3"]}}})
删除字符串数组中元素示例
// 不会删除数据, 因为$pull会把入参的数组看成是要删除集合数组中的一个元素, 自然是没有匹配的数据用于删除
db.users.updateMany({ "username" : "james"}, { "$pull" : { "favorites.movies" : [ "小电影 2 " , "小 电影 3"]}})
// 正确的写法
db.users.updateMany({ "username" : "james"}, { "$pull" : { "favorites.movies" : "复仇者联盟"}})
// 会删除所有匹配的数据
db.users.updateMany({ "username" : "james"}, { "$pullAll" : { "favorites.movies" : [ "小电影 2 " , " 小电影 3"]}})
// 使用$in也可以让$pull具有$pullAll的功能
db.users.updateMany({ "username" : "james"}, { "$pull" : { "favorites.movies" : {$in:[ "小电影 2 " , "小电影 3"]}}})
向对象数组中插入元素
增加一条
db.users.updateOne({
"username": "james"
}, {
"$push": { // 自动添加的是数组
"comments": { // 如果没有comments字段, 会自动添加字段
"author": "lison23",
"content": "ydddyyytttt",
"commentTime": ISODate("2019-01-06T00:00:00")
}
}
})
增加两条: 使用$each
db.users.updateOne({
"username": "james"
}, {
"$push": {
"comments": {
"$each": [{ // 避免数组当成了一个数据插入
"author": "lison22",
"content": "yyyytttt",
"commentTime": ISODate("2019-07-06T00:00: 00")
}, {
"author": "lison23",
"content": "ydddyyytttt",
"commentTime": ISODate("2019-06-06T00:00:00")
}]
}
}
})
新增并排序
db.users.updateOne({
"username": "james"
}, {
"$push": {
"comments": {
"$each": [{ // 拉平操作
"author": "lison22",
"content": "yyyytttt",
"commentTime": ISODate("2019-04-06T00:00: 00")
}, {
"author": "lison23",
"content": "ydddyyytttt",
"commentTime": ISODate("2019-05-06T00:00:00")
}],
$sort: { // 排序操作
"commentTime": - 1
}
}
}
})
删除对象数组中元素示
db.users.update({"username":"james"}, {"$pull":{"comments":{"author":"lison22"}}})
// 多字段删除
db.users.update({"username":"lison"}, {"$pull":{"comments":{"author":"lison5", "content":"ooxx"}}})
更新对象数组中元素,$符号示例
db.users.updateMany({
"username": "james",
"comments.author": "lison23"
}, {
"$set": {
"comments.$.content": "xxoo",
"comments.$.author": "lison10"
}
})
含义:精确修改某人某一条精确的评论,如果有多个符合条件的数据,则修改第一条数据。 无法批量修改数组元素,也无法对数组元素做批量更新
findAndModify 命令示例
db.fam.findAndModify({query:{name:'morris1'}, update:{$inc:{age:1}}, 'new':true});
测试脚本
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JavaUpdateObjArray {
private static final Logger logger = LoggerFactory.getLogger(JavaUpdateObjArray.class);
private MongoDatabase db;
private MongoCollection<Document> collection;
@Resource(name = "mongo")
private MongoClient client;
@Before
public void init() {
db = client.getDatabase("lison");
collection = db.getCollection("users");
}
//--------------------------------------upsert demo--------------------------------------------------------------
//测试upsert
//db.users.update({"username":"cang"},{"$set":{"age":18}},{"upsert":true})
@Test
public void upsertTest() {
Bson filter = eq("username", "cang");
Bson update = set("age", 18);
UpdateOptions upsert = new UpdateOptions().upsert(true);
UpdateResult updateOne = collection.updateOne(filter, update, upsert);
System.out.println(updateOne.getModifiedCount());
System.out.println(updateOne.getUpsertedId());
}
//测试unset,删除字段示例
//db.users.updateMany({"username":"lison"},{"$unset":{"country":"","age":""}})
@Test
public void unsetTest() {
Bson filter = eq("username", "lison");
Bson country = unset("country");
Bson age = unset("age");
Bson update = combine(country, age);
UpdateResult updateOne = collection.updateMany(filter, update);
System.out.println(updateOne.getModifiedCount());
System.out.println(updateOne.getUpsertedId());
}
//测试rename,更新字段名称示例
//db.users.updateMany({"username":"lison"},{"$rename":{"lenght":"height", "username":"name"}})
@Test
public void renameTest() {
Bson filter = eq("username", "lison");
Bson rename1 = rename("lenght", "height");
Bson rename2 = rename("username", "name");
Bson update = combine(rename1, rename2);
UpdateResult updateOne = collection.updateMany(filter, update);
System.out.println(updateOne.getModifiedCount());
System.out.println(updateOne.getUpsertedId());
}
//测试pull pullAll,删除字符串数组中元素示例
// db.users.updateMany({ "username" : "james"}, { "$pull" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
// db.users.updateMany({ "username" : "james"}, { "$pullAll" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
@Test
public void pullAllTest() {
Bson filter = eq("username", "james");
Bson pull = pull("favorites.movies", Arrays.asList("小电影2 ", "小电影3"));
UpdateResult updateOne = collection.updateMany(filter, pull);
System.out.println(updateOne.getModifiedCount());
System.out.println(updateOne.getUpsertedId());
Bson pullAll = pullAll("favorites.movies", Arrays.asList("小电影2 ", "小电影3"));
updateOne = collection.updateMany(filter, pullAll);
System.out.println(updateOne.getModifiedCount());
System.out.println(updateOne.getUpsertedId());
}
//--------------------------------------insert demo--------------------------------------------------------------
//给james老师增加一条评论($push)
//db.users.updateOne({"username":"james"},
// {"$push":{"comments":{"author":"lison23",
// "content":"ydddyyytttt",
// "commentTime":ISODate("2019-01-06T00:00:00")}}})
@Test
public void addOneComment() {
Document comment = new Document().append("author", "lison23").append("content", "ydddyyytttt")
.append("commentTime", getDate("2019-01-06"));
Bson filter = eq("username", "james");
Bson update = push("comments", comment);
UpdateResult updateOne = collection.updateOne(filter, update);
System.out.println(updateOne.getModifiedCount());
}
// 给james老师批量新增两条评论($push,$each)
// db.users.updateOne({"username":"james"},
// {"$push":{"comments":
// {"$each":[{"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-02-06T00:00:00")},
// {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-03-06T00:00:00")}]}}})
@Test
public void addManyComment() {
Document comment1 = new Document().append("author", "lison33").append("content", "lison33lison33")
.append("commentTime", getDate("2019-02-06"));
Document comment2 = new Document().append("author", "lison44").append("content", "lison44lison44")
.append("commentTime", getDate("2019-03-06"));
Bson filter = eq("username", "james");
Bson pushEach = pushEach("comments", Arrays.asList(comment1, comment2));
UpdateResult updateOne = collection.updateOne(filter, pushEach);
System.out.println(updateOne.getModifiedCount());
}
// 给james老师批量新增两条评论并对数组进行排序($push,$eachm,$sort)
// db.users.updateOne({"username":"james"},
// {"$push": {"comments":
// {"$each":[ {"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-04-06T00:00:00")},
// {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-05-06T00:00:00")} ],
// $sort: {"commentTime":-1} } } })
@Test
public void addManySortComment() {
Document comment1 = new Document().append("author", "lison00").append("content", "lison00lison00")
.append("commentTime", getDate("2019-04-06"));
Document comment2 = new Document().append("author", "lison01").append("content", "lison01lison01")
.append("commentTime", getDate("2019-05-06"));
Bson filter = eq("username", "james");
Document sortDoc = new Document().append("commentTime", -1);
PushOptions pushOption = new PushOptions().sortDocument(sortDoc);
Bson pushEach = pushEach("comments", Arrays.asList(comment1, comment2), pushOption);
UpdateResult updateOne = collection.updateOne(filter, pushEach);
System.out.println(updateOne.getModifiedCount());
}
//--------------------------------------delete demo--------------------------------------------------------------
// 删除lison1对james的所有评论 (批量删除)
// db.users.update({"username":“james"},
// {"$pull":{"comments":{"author":"lison33"}}})
@Test
public void deleteByAuthorComment() {
Document comment = new Document().append("author", "lison33");
Bson filter = eq("username", "james");
Bson update = pull("comments", comment);
UpdateResult updateOne = collection.updateOne(filter, update);
System.out.println(updateOne.getModifiedCount());
}
// 删除lison5对lison评语为“lison是苍老师的小迷弟”的评论(精确删除)
// db.users.update({"username":"lison"},
// {"$pull":{"comments":{"author":"lison5",
// "content":"lison是苍老师的小迷弟"}}})
@Test
public void deleteByAuthorContentComment() {
Document comment = new Document().append("author", "lison5").append("content", "lison是苍老师的小迷弟");
Bson filter = eq("username", "lison");
Bson update = pull("comments", comment);
UpdateResult updateOne = collection.updateOne(filter, update);
System.out.println(updateOne.getModifiedCount());
}
//--------------------------------------update demo--------------------------------------------------------------
// db.users.updateMany({"username":"james","comments.author":"lison01"},
// {"$set":{"comments.$.content":"xxoo",
// "comments.$.author":"lison10" }})
// 含义:精确修改某人某一条精确的评论,如果有多个符合条件的数据,则修改最后一条数据。无法批量修改数组元素
@Test
public void updateOneComment() {
Bson filter = and(eq("username", "james"), eq("comments.author", "lison01"));
Bson updateContent = set("comments.$.content", "xxoo");
Bson updateAuthor = set("comments.$.author", "lison10");
Bson update = combine(updateContent, updateAuthor);
UpdateResult updateOne = collection.updateOne(filter, update);
System.out.println(updateOne.getModifiedCount());
}
//--------------------------------------findandModify demo--------------------------------------------------------------
//使用findandModify方法在修改数据同时返回更新前的数据或更新后的数据
//db.fam.findAndModify({query:{name:'morris1'},
// update:{$inc:{age:1}},
// 'new':true});
@Test
public void findAndModifyTest() {
Bson filter = eq("name", "morris1");
Bson update = inc("age", 1);
// //实例化findAndModify的配置选项
FindOneAndUpdateOptions fauo = new FindOneAndUpdateOptions();
// //配置"new":true
fauo.returnDocument(ReturnDocument.AFTER);//
MongoCollection<Document> numCollection = db.getCollection("fam");
Document ret = numCollection.findOneAndUpdate(filter, update, fauo);
System.out.println(ret.toJson());
}
private Date getDate(String string) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date parse = null;
try {
parse = sdf.parse(string);
} catch (ParseException e) {
e.printStackTrace();
}
return parse;
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringUpdateObjArray {
private static final Logger logger = LoggerFactory.getLogger(SpringUpdateObjArray.class);
@Resource
private MongoOperations tempelate;
//--------------------------------------upsert demo--------------------------------------------------------------
//测试upsert
//db.users.update({"username":"cang"},{"$set":{"age":18}},{"upsert":true})
@Test
public void upsertTest() {
Query query = query(Criteria.where("username").is("cang"));
Update set = new Update().set("age", 18);
UpdateResult upsert = tempelate.upsert(query, set, User.class);
System.out.println(upsert.getModifiedCount());
System.out.println(upsert.getUpsertedId());
}
//测试unset,删除字段示例
//db.users.updateMany({"username":"lison"},{"$unset":{"country":"","age":""}})
@Test
public void unsetTest() {
Query query = query(Criteria.where("username").is("lison"));
Update unset = new Update().unset("country").unset("age");
UpdateResult upsert = tempelate.updateMulti(query, unset, User.class);
System.out.println(upsert.getModifiedCount());
}
//测试rename,更新字段名称示例
//db.users.updateMany({"username":"lison"},{"$rename":{"lenght":"height", "username":"name"}})
@Test
public void renameTest() {
Query query = query(Criteria.where("username").is("lison"));
Update rename = new Update().rename("lenght", "height").rename("username", "name");
UpdateResult upsert = tempelate.updateMulti(query, rename, User.class);
System.out.println(upsert.getModifiedCount());
}
//测试pull pullAll,删除字符串数组中元素示例
// db.users.updateMany({ "username" : "james"}, { "$pull" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
// db.users.updateMany({ "username" : "james"}, { "$pullAll" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
@Test
public void pullAllTest() {
Query query = query(Criteria.where("username").is("james"));
Update pull = new Update().pull("favorites.movies", Arrays.asList("小电影2 ", "小电影3"));
UpdateResult upsert = tempelate.updateMulti(query, pull, User.class);
System.out.println(upsert.getModifiedCount());
query = query(Criteria.where("username").is("james"));
Update pullAll = new Update().pullAll("favorites.movies", new String[] {"小电影2 ", "小电影3"});
upsert = tempelate.updateMulti(query, pullAll, User.class);
System.out.println(upsert.getModifiedCount());
}
//--------------------------------------insert demo--------------------------------------------------------------
//给james老师增加一条评论($push)
//db.users.updateOne({"username":"james"},
// {"$push":{"comments":{"author":"lison23",
// "content":"ydddyyytttt",
// "commentTime":ISODate("2019-01-06T00:00:00")}}})
@Test
public void addOneComment() {
Query query = query(Criteria.where("username").is("james"));
Comment comment = new Comment();
comment.setAuthor("lison23");
comment.setContent("ydddyyytttt");
comment.setCommentTime(getDate("2019-01-06"));
Update push = new Update().push("comments", comment);
UpdateResult updateFirst = tempelate.updateFirst(query, push, User.class);
System.out.println(updateFirst.getModifiedCount());
}
// 给james老师批量新增两条评论($push,$each)
// db.users.updateOne({"username":"james"},
// {"$push":{"comments":
// {"$each":[{"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-02-06T00:00:00")},
// {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-03-06T00:00:00")}]}}})
@Test
public void addManyComment() {
Query query = query(Criteria.where("username").is("james"));
Comment comment1 = new Comment();
comment1.setAuthor("lison55");
comment1.setContent("lison55lison55");
comment1.setCommentTime(getDate("2019-02-06"));
Comment comment2 = new Comment();
comment2.setAuthor("lison66");
comment2.setContent("lison66lison66");
comment2.setCommentTime(getDate("2019-03-06"));
//Update push = new Update().pushAll("comments", new Comment[]{comment1,comment2});
//Update push = new Update().push("comments", new Comment[]{comment1,comment2});
Update push = new Update().push("comments").each(new Comment[] {comment1, comment2});
UpdateResult updateFirst = tempelate.updateFirst(query, push, User.class);
System.out.println(updateFirst.getModifiedCount());
}
// 给james老师批量新增两条评论并对数组进行排序($push,$eachm,$sort)
// db.users.updateOne({"username":"james"},
// {"$push": {"comments":
// {"$each":[ {"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-04-06T00:00:00")},
// {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-05-06T00:00:00")} ],
// $sort: {"commentTime":-1} } } })
@Test
public void addManySortComment() {
Query query = query(Criteria.where("username").is("james"));
Comment comment1 = new Comment();
comment1.setAuthor("lison77");
comment1.setContent("lison55lison55");
comment1.setCommentTime(getDate("2019-04-06"));
Comment comment2 = new Comment();
comment2.setAuthor("lison88");
comment2.setContent("lison66lison66");
comment2.setCommentTime(getDate("2019-05-06"));
Update update = new Update();
PushOperatorBuilder pob = update.push("comments");
pob.each(comment1, comment2);
pob.sort(Sort.by(Direction.DESC, "commentTime"));
System.out.println("---------------");
UpdateResult updateFirst = tempelate.updateFirst(query, update, User.class);
System.out.println(updateFirst.getModifiedCount());
}
//--------------------------------------delete demo--------------------------------------------------------------
// 删除lison1对james的所有评论 (批量删除)
// db.users.update({"username":“james"},
// {"$pull":{"comments":{"author":"lison23"}}})
@Test
public void deleteByAuthorComment() {
Query query = query(Criteria.where("username").is("james"));
Comment comment1 = new Comment();
comment1.setAuthor("lison55");
/* BasicDBObject comment1 = new BasicDBObject ();
comment1.put("author","lison23");*/
Update pull = new Update().pull("comments", comment1);
UpdateResult updateFirst = tempelate.updateFirst(query, pull, User.class);
System.out.println(updateFirst.getModifiedCount());
}
// 删除lison5对lison评语为“lison是苍老师的小迷弟”的评论(精确删除)
// db.users.update({"username":"lison"},
// {"$pull":{"comments":{"author":"lison5",
// "content":"lison是苍老师的小迷弟"}}})
@Test
public void deleteByAuthorContentComment() {
Query query = query(Criteria.where("username").is("lison"));
Comment comment1 = new Comment();
comment1.setAuthor("lison5");
comment1.setContent("lison是苍老师的小迷弟");
Update pull = new Update().pull("comments", comment1);
UpdateResult updateFirst = tempelate.updateFirst(query, pull, User.class);
System.out.println(updateFirst.getModifiedCount());
}
//--------------------------------------update demo--------------------------------------------------------------
// db.users.updateMany({"username":"james","comments.author":"lison1"},
// {"$set":{"comments.$.content":"xxoo",
// "comments.$.author":"lison10" }})
// 含义:精确修改某人某一条精确的评论,如果有多个符合条件的数据,则修改最后一条数据。无法批量修改数组元素
@Test
public void updateOneComment() {
Query query = query(where("username").is("lison").and("comments.author").is("lison4"));
Update update = update("comments.$.content", "xxoo").set("comments.$.author", "lison11");
UpdateResult updateFirst = tempelate.updateFirst(query, update, User.class);
System.out.println(updateFirst.getModifiedCount());
}
//--------------------------------------findandModify demo--------------------------------------------------------------
//使用findandModify方法在修改数据同时返回更新前的数据或更新后的数据
//db.fam.findAndModify({query:{name:'morris1'},
// update:{$inc:{age:1}},
// 'new':true});
@Test
public void findAndModifyTest() {
Query query = query(where("name").is("morris1"));
Update update = new Update().inc("age", 1);
FindAndModifyOptions famo = FindAndModifyOptions.options().returnNew(true);
Doc doc = tempelate.findAndModify(query, update, famo, Doc.class);
System.out.println(doc.toString());
}
private Date getDate(String string) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date parse = null;
try {
parse = sdf.parse(string);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return parse;
}
}
A. 查看一个人的信息,打开页面只显示三条评论
B. 点击评论的下一页按钮,新加载三条评论
C. 默认按照评论时间降序,但是也可以选择按照姓名排序
A. 数组中数据的排序问题?
B. 数组中的数据怎么按照指定的方式进行排序?
C. 每次仅仅加载三条评论信息(可以包含 id 字段)?
A. 添加数据时注意排序
B. 查询的时候投影是有技巧的
C. 排序考虑聚合?
(1)考虑到默认顺序,所以新增评论时,使用$sort 运算符按照评论时间降序排序;
db.users.updateOne({
username: "lison"
}, {
$push: {
comments: {
$each: [{
author: "james",
content: "xxoo",
commentTime: ISODate("2018-01-01T04:09:00.000Z")
}],
$sort: {
commcommentTime: - 1
}
}
}
});
注意: s o r t 操作符必须和 sort 操作符必须和 sort操作符必须和each 配合使用
(2)由于评论已经按照时间降序排序,所以查看人员时直接加载最新的三条评论;
db.users.find({
"username": "lison"
}, {
"comments": {
"$slice": [0, 3]
}
}).pretty()
(3)点击评论的下一页按钮,新加载后三条评论(注意:仅仅加载评论的数据,人员信息 不加载)
db.users.find({
"username": "lison"
}, {
"comments": { // 投影还可以进行分片操作, 没有值确定0,1就默认是全是1
"$slice": [3, 3]
},
"$id": 1
}).pretty();
(4)如果有多种排序需求怎么处理?使用聚合
db.users.aggregate([{
"$match": {
"username": "lison"
}
}, {
"$unwind": "$comments"
}, {
$sort: {
"comments.commentTime": 1
}
}, {
"$project": {
"comments": 1
}
}, {
"$skip": 0
}, {
"$limit": 3
}])
// 新增评论时,使用$sort运算符进行排序,插入评论后,再按照评论时间降序排序
public void demoStep1() {
Bson filter = eq("username", "lison");
Document comment =
new Document().append("author", "cang").append("content", "lison是我的粉丝").append("commentTime", new Date());
// $sort: {"commentTime":-1}
Document sortDoc = new Document().append("commentTime", -1);
PushOptions sortDocument = new PushOptions().sortDocument(sortDoc);
// $each
Bson pushEach = Updates.pushEach("comments", Arrays.asList(comment), sortDocument);
UpdateResult updateOne = collection.updateOne(filter, pushEach);
System.out.println(updateOne.getModifiedCount());
}
@Test
// 查看人员时加载最新的三条评论;
// db.users.find({"username":"lison"},{"comments":{"$slice":[0,3]}}).pretty()
public void demoStep2() {
FindIterable<Document> find = collection.find(eq("username", "lison")).projection(slice("comments", 0, 3));
printOperation(find);
}
@Test
// 点击评论的下一页按钮,新加载三条评论
// db.users.find({"username":"lison"},{"comments":{"$slice":[3,3]},"$id":1}).pretty();
public void demoStep3() {
// {"username":"lison"}
Bson filter = eq("username", "lison");
// "$slice":[3,3]
Bson slice = slice("comments", 3, 3);
// "$id":1
Bson includeID = include("id");
// {"comments":{"$slice":[3,3]},"$id":1})
Bson projection = fields(slice, includeID);
FindIterable<Document> find = collection.find(filter).projection(projection);
printOperation(find);
}
@Test
/**
* db.users.aggregate([{"$match":{"username":"lison"}},
{"$unwind":"$comments"},
{$sort:{"comments.commentTime":-1}},
{"$project":{"comments":1}},
{"$skip":6},
{"$limit":3}])
*/
// 如果有多种排序需求怎么处理,使用聚合
public void demoStep4() {
final List<Document> ret = new ArrayList<Document>();
Block<Document> printBlock = getBlock(ret);
List<Bson> aggregates = new ArrayList<Bson>();
aggregates.add(match(eq("username", "lison")));
aggregates.add(unwind("$comments"));
aggregates.add(sort(orderBy(ascending("comments.commentTime"))));
aggregates.add(project(fields(include("comments"))));
aggregates.add(skip(0));
aggregates.add(limit(3));
AggregateIterable<Document> aggregate = collection.aggregate(aggregates);
printOperation(ret, printBlock, aggregate);
}
show dbs :显示数据库列表
show collections :显示集合列表
db : 显示当前数据库
db.stats() :显示数据库信息
db.serverStatus() : 查看服务器状态
db.dropDatabase():删除数据库
db.help(),db.collection.help():内置帮助,显示各种方法的说明;
db.users.find().size():获取查询集合的数量;
db.users.drop():删除集合;
在生产环境,不要用 kill -9 关掉 mongodb 的进程,很可能造成 mongodb 的数据丢失;
优雅的关机:
use admin
db.shutdownServer()
mongod --shutdown -f mongodb.conf (service mongodb start)
mongod --shutdown -f /soft/mongodb/conf/mgdb.conf --auth
mongodump -p 27022 -d mgdb-o /soft/backup
-p :端口; -d :备份的数据库名称 ; -o:指定备份的路径
其本质为:执行查询,然后写入文件;
mongorestore -p 27022
-d mydb /soft/backup/lison --drop
–drop 已存在 lison 库则删除原数据库,去掉–drop 则是合并
mongoexport -p 27022 -d lison -c users -f id,username,age,salary --type=json -o
/soft/backup/users.json
-c :指定导出的集合; -f :要导出的字段; --type:导出的文件格式类型[csv,json]
mongoimport -p 27022 -d lison -c users /soft/backup/users.json --upsert
–upsert 表示更新现有数据,如果不适用—upsert,则导入时已经存在的文档会报 id 重复,数据不再插入,也可以使用—drop 删除原有数据
db.createUser({
'user': 'boss',
'pwd': 'boss',
'roles': [{
'role': 'userAdminAnyDatabase',
'db': 'admin'
}]
});
db.createUser({
'user': 'lison',
'pwd': 'lison',
'roles': [{
'role': 'readWrite',
'db': 'lison'
}]
})
服务器启动需要加上 auth 参数连接服务器才需要验证
mongod -f /soft/mongodb/conf/mgdb.conf --auth
切换到数据库上,才能给当前数据库创建用户
启动 mongodb
数据库增加安全模式后,初始化一个“userAdminAnyDatabase”非常重要
通过客户端连接,使用 admin 数据库, 执行如下脚本:
db.createUser({
'user': 'boss',
'pwd': 'boss',
'roles': [{
'role': 'userAdminAnyDatabase',
'db': 'admin'
}]
})
使用刚创建成功的用户登录:db.auth(“boss”,“boss”);
切换到 lison 数据库(use lison),创建读写权限用户:
db.createUser({
'user': 'lison',
'pwd': 'lison',
'roles': [{
'role': 'readWrite',
'db': 'lison'
}]
})
也可以以非 auth 模式启动,然后创建用户后,用 auth 模式启动
db.createUser({
'user': 'root',
'pwd': 'root',
'roles': [{
'role': 'root',
'db': 'admin'
}]
})
MongoCredential 类包括每个受支持的身份验证机制的静态工厂方法。
public static MongoCredential createCredential(final String userName, final String database, final char[] password) {
return new MongoCredential(null, userName, database, password);
}
import static com.mongodb.client.model.Filters.in;
public class JavaAuthTest {
private static final Logger logger = LoggerFactory.getLogger(JavaAuthTest.class);
private MongoDatabase db;
private MongoCollection<Document> collection;
private MongoClient client;
@Before
public void init() {
MongoCredential createCredential = MongoCredential.createCredential("lison", "lison", "lison".toCharArray());
MongoClientOptions mco =
MongoClientOptions.builder().writeConcern(WriteConcern.JOURNALED).connectionsPerHost(100)
.readPreference(ReadPreference.secondary()).threadsAllowedToBlockForConnectionMultiplier(5)
.maxWaitTime(120000).connectTimeout(10000).build();
List<ServerAddress> asList = Arrays.asList(new ServerAddress("localhost", 27017));
this.client = new MongoClient(asList, createCredential, mco);
db = client.getDatabase("lison");
collection = db.getCollection("users");
}
// -----------------------------操作符使用实例------------------------------------------
// db.users.find({"username":{"$in":["lison", "mark", "james"]}}).pretty()
// 查询姓名为lison、mark和james这个范围的人
@Test
public void testInOper() {
Bson in = in("username", "lison", "mark", "james");
FindIterable<Document> find = collection.find(in);
printOperation(find);
}
// ---------------------------------------------------------------------------
//返回对象的处理器,打印每一行数据
private Block<Document> getBlock(final List<Document> ret) {
Block<Document> printBlock = new Block<Document>() {
@Override
public void apply(Document t) {
logger.info("---------------------");
logger.info(t.toJson());
logger.info("---------------------");
ret.add(t);
}
};
return printBlock;
}
//打印查询出来的数据和查询的数据量
private void printOperation(FindIterable<Document> find) {
final List<Document> ret = new ArrayList<Document>();
Block<Document> printBlock = getBlock(ret);
find.forEach(printBlock);
System.out.println(ret.size());
ret.removeAll(ret);
}
}
<mongo:mongo-client id="mongo" host="localhost" port="27017">
<mongo:client-options
write-concern="ACKNOWLEDGED"
threads-allowed-to-block-for-connection-multiplier="5"
max-wait-time="1200"
connect-timeout="1000"/>
mongo:mongo-client>