java mongodb 查询语句_mongodb-java-driver做基本的CRUD--基本查询

title: mongodb-2 mongodb-java-driver做基本的CRUD–基本查询

date: 2017-01-11 16:25:59

tags:

categories: mongodb

如何连接mongodb?

http://mongodb.github.io/mongo-java-driver/3.4/driver/tutorials/connect-to-mongodb/

其中MongoClient类比jdbc时的连接池,全局唯一。MongoCollection类似于Connection

不同的是,使用完MongoCollection后并不需要像JDBC,redis的jedis客户端一样手动返回,很方便。

利用Document构建查询语句

mongodb-java-driver为我们提供了2种方式。一种是用Document(类似Map)来构建一个JSON式的对象。怎么个搞法呢?

@Test

public void testQuery() throws Exception {

Document document = new Document("price", new Document("$gte", 1)

.append("$lt", 500))

.append("name", "shirt");

System.out.println(document.toJson());

MongoCollection clothCollection = mongoClient.getDatabase("test").getCollection("Cloth");

FindIterable results = clothCollection.find(document);

results.forEach((Consumer super Document>) System.out::println);

}

说实话用json(或者说BSON)的样式作为交互语言,给习惯了sql的我来说本来就十分别扭了,翻译成这个样子之后,不管你怎么看,我觉得简直是崩溃。研究了很久之后,我发现Document提供了2个便利方法。

一个是Document.parse将一个JSON字符串反序列化为Document,

一个是toJson可以把Document序列化为json字符串。

这样tojson方法可以作为一种查看你最后写的BSON语句正确与否的手段。如果记录在日志里面,就可以像打印sql一样留下记录了!

/**

* 使用mongodb时怎么去判断自己最后写出的语句对不对呢?

*

* @throws Exception

*/

@Test

public void testToJson() throws Exception {

Document document = new Document("price", new Document("$gte", 1)

.append("$lt", 5))

.append("name", "shirt");

String string = document.toJson();

String s = document.toString();

System.out.println( s);

System.out.println(string);

}

输出:

Document{{price=Document{{$gte=1, $lt=5}}, name=shirt}}

{ "price" : { "$gte" : 1, "$lt" : 5 }, "name" : "shirt" }

前者是toString,后者是toJson的结果。可以看见tojson可以直接复制到GUI里面调试。

使用Filters工具类简写

@Test

public void testQuery2() throws Exception {

MongoCollection clothCollection = mongoClient.getDatabase("test").getCollection("Cloth");

// 此Document等于下面的简写

// new Document("stars", new Document("$gte", 2)

// .append("$lt", 5))

// .append("categories", "Bakery")

clothCollection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery")))

.forEach((Consumer super Document>) System.out::println);

}

很容易理解的工具类,不过这样写无法利用toJson方法,因为生成的不是Document。

限制Document返回的Field

@Test

public void testKey() throws Exception {

FindIterable results = clothCollection.find().projection(Projections.include("name"));

results.forEach((Consumer super Document>) System.out::println);

}

输出:

Document{{_id=586f4c462148d00ffe8d9787, name=shirt}}

如上,返回的仅仅只有_id 和name。

这段实际在shell中就是:db.Cloth.find(null,{“name”:1}); 1表示include,0表示exclude,其中_id在没有指明的时候默认回传。

通过主键查询ID

@Test

public void queryDate() throws Exception {

// FindIterable results = clothCollection.find(Filters.eq("_id", "58759260bc497244060ba7c0"));

FindIterable results = clothCollection.find(new Document("_id", new ObjectId("58759260bc497244060ba7c0")));

results.forEach((Consumer super Document>) document -> {

System.out.println(document);

});

}

注意Mongodb的主键类型是ObjectID,需要自己去构造。

分页

@Test

public void testPagination() throws Exception {

int pageNum=1;

int pageSize=3;

FindIterable results = clothCollection.find().skip((pageNum-1)*pageSize).limit(pageSize);

long count = clothCollection.count();

System.out.println("count :"+count);

results.forEach((Consumer super Document>) document -> {

System.out.println(document);

});

}

mongodb的分skip和count都是非常耗时的操作,数据量达到几百万的时候,最好别进行count。

分页最好只显示前面几十页即可。

或者使用上一页的id作为条件,排序查询代替分页(这样做的弊端是翻页的时候不能跳页,好处是可以一直翻下去,而且不会变慢,其实感觉这样的需求并不强)。

所以一般常见的做法就是别count,分页只拿前面部分。

OR 或查询

@Test

public void testOR() throws Exception {

// Document document = new Document("$or", new Object[]{new Document("label", "adfad"), new Document("name", "T")});

// Document[] documentsParam = new Document[]{new Document("label", "adfad"), new Document("name", "T")};

ArrayList documentsParam = Lists.newArrayList(new Document("label", "adfad"), new Document("name", "T"));

Document document = new Document("$or", documentsParam);

FindIterable documents = clothCollection.find(document);

documents.forEach((Consumer super Document>) document1 -> {

System.out.println(document1);

});

}

上面的代码查询的是name=T或者label=adfad的文档。

shell就是:find({ “$or” : [{ “label” : “adfad” }, { “name” : “T” }] })

值得一提的是驱动能认识ArrayList,却没有Array的解析器……

IN查询

@Test

public void testIN() throws Exception {

Bson queryParam = Filters.in("name", "T", "shirt");

FindIterable documents = clothCollection.find(queryParam);

documents.forEach((Consumer super Document>) document1 -> System.out.println(document1));

}

in也可以在单filed的时候或

shell :find{“name”,{“$in” : [ “shirt”,”T” ]}}

上面代码用的Filters辅助类,参数既可以接受可变参数,也可以是List

NULL查询

@Test

public void testNULL() throws Exception {

FindIterable results = clothCollection.find(new Document("name", null));

results.forEach((Consumer super Document>) document1 -> System.out.println(document1));

}

输出:

Document{{_id=58735ed5bc49722dd7b74f91, name=null}}

Document{{_id=58759260bc497244060ba7c0, date=Wed Jan 11 10:03:12 CST 2017}}

可以看到单纯的传 name:null这样的条件,将会匹配到name的值本身为null的Document,也会匹配到根本就没有name这个field的Document!!

匹配有name字段并且name字段值为null的Document

@Test

public void testNULL2() throws Exception {

ArrayList objects = Lists.newArrayList();

objects.add(null);

FindIterable documents = clothCollection.find(Filters.and(Filters.in("name",objects), Filters.exists("name")));

documents.forEach((Consumer super Document>) document1 -> System.out.println(document1));

}

shell即为:{name:{“$in”:[null],”$exits”:true}}

没有$eq 这种操作符……只能用$in来代替

比较尴尬的是,null对于java来说也是很特殊的字段,注意上面代码中,我是怎么传null到list里面的……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值