项目中使用的是 Morphia 框架 的Datastore 来操作mongodb, 不的不说Morphia 还是非常强大的,满足了大部分的需求,知道有一天,我需要用到文档查询,想到了使用 hasThisElement(Object obj) 方法,
datastore.createQuery(ContractCustomField.class).field("name")
.hasThisElement(Object);
首先看一下我的数据结构
{
"name":"其他的一些字段",
"customFields" : [
{
"id" : "5c3d48cbe4b05b2f69564f90",
"fieldName" : "文本非必填",
"type" : 1,
"valueStr" : ""
},
{
"id" : "5c3d48dbe4b05b2f69564f91",
"fieldName" : "文本必填",
"type" : 1,
"valueStr" : "我添加了文办"
},
{
"id" : "5c3d48e5e4b05b2f69564f92",
"fieldName" : "数字",
"type" : 2,
"valueDou" : 33.55
},
{
"id" : "5c3d494ee4b05b2f69564f96",
"fieldName" : "日期必选",
"type" : 3,
"valueDate" : "2019-01-14T16:00:00.000Z"
},
{
"id" : "5c3d497ae4b05b2f69564f98",
"fieldName" : "多选必填",
"type" : 5,
"valueList" : [
"多必2",
"多必1"
]
},
{
"id" : "5c3d4903e4b05b2f69564f93",
"fieldName" : "单选必填",
"type" : 4,
"valueSingle" : "男"
},
{
"id" : "5c3d4934e4b05b2f69564f94",
"fieldName" : "单选非必填",
"type" : 4,
"valueSingle" : "不选2"
}
]}
我要做的工作就是对customFields 列进行筛选, 比如 { "id" : "5c3d48cbe4b05b2f69564f90", "valueStr" }: "我添加了文办"
并且 {"id" : "5c3d48e5e4b05b2f69564f92", "valueDou" : {"$gt":23 , "$lt":45 }}, 是一个数组中的对象,满足某个条件, 日期的区间, 数字的大于等于等,在使用 hasThisElement(Object obj) 方法时,尝试多多次,发现还是不能满足, 对象里的属性不知道如何并行 > < 等比较,所以只好放弃,转到直接操作mongo的api ,下面我们来看下使用MongoDB 的 BasicDBObject 和BasicDBList ,是如何实现高级的文档查询;
首先了解一下 BasicDBObject 和 BasicDBList;
BasicDBObject 基础对象,所有的对象操作用该方法,
select * from Contract where tenantId = 123123 and status in (1,3, 4);
List list = new ArrayList();
添加list 数据,省略...
BasicDBObject query = new BasicDBObject("tenantId", 123123);
query.append("status", new BasicDbObject("$IN", list))
DBCollection collection = datastore.getCollection(Contract.class);
DBCursor cursor = collection.find(query);
这是BasicDBObject 的简单操作
BasicDBList, 可以把它看成一个对象集合, 我觉也也可以用List<BasicDBObject> 代替,目前还不知道会有没有别的影响,
BasicDBList basicDBList = new BasicDBList();
basicDBList.add(new BasicDBObject("customFields", new BasicDBObject(QueryOperators.ELEM_MATCH,textObject)));
query.put(QueryOperators.AND, basicDBList);
db.getCollection('Contract').find({"name": "合同1656",
"$and":[{"customFields":{"$elemMatch":{"id":"5c3c48d8e4b074eccea0a498", "valueDou":{"$gte":33.55, "$lt":34}}}},
{"customFields":{"$elemMatch":{"id":"5c35d9a7e4b01664aced345c", "valueStr":"我添加了文办"}}} ] })
{
"projectId":10000030846,
"name":{
"$regex":"^.*合同1124.*$",
"$options":"i"
},
"payReceive.received":0,
"$and":[
{
"customFields":{
"$elemMatch":{
"id":"5c3d48e5e4b05b2f69564f92",
"valueDou":{
"$gte":33,
"$lt":35
}
}
}
},
{
"customFields":{
"$elemMatch":{
"id":"5c3d494ee4b05b2f69564f96",
"valueDate":{
"$gte":{
"$date":"2019-01-14T16:00:00.000Z"
},
"$lt":{
"$date":"2019-01-14T16:01:39.999Z"
}
}
}
}
},
{
"customFields":{
"$elemMatch":{
"id":"5c3d48dbe4b05b2f69564f91",
"valueStr":{
"$regex":"^.*添加.*$",
"$options":"i"
}
}
}
},
{
"customFields":{
"$elemMatch":{
"id":"5c3d497ae4b05b2f69564f98",
"valueList":{
"$in":[
"多必2",
"多必1"
]
}
}
}
}
]
}
设置完 BasicDBObject 查询, Contract 是一个实体类, 请大家忽略
DBCollection collection = datastore.getCollection(Contract.class);
DBCursor cursor = collection.find(query);
if (null != searchParam.getLimit() && null != searchParam.getOffset()) {
cursor.skip(searchParam.getOffset()).limit(searchParam.getLimit());
}
cursor.sort(new BasicDBObject("createdAt", -1));
List<Contract> contracts = new ArrayList<>();
Iterator<DBObject> iterator = cursor.iterator();
while (iterator.hasNext()) {
DBObject next = iterator.next();
Contract contract = morphia.fromDBObject(Contract.class, next);
contracts.add(contract);
}
利用 BasicDBObject 和 BasicDBList 即可完成 所有的基本查询操作