Java BasicDBObject $elemMatch 实现对文档的高级查询

项目中使用的是 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 即可完成 所有的基本查询操作

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值