我想添加或者&并且同时对我的查询对象进行了子句但是我一直得到以下错误
由于com.mongodb.BasicDBObject的限制,你不能添加第二个'null'标准吗?
例如
query.addCriteria(new Criteria().orOperator(Some Critera);
query.addCriteria(new Criteria().andOperator(Some Critera);
任何人都可以帮我解决这个问题吗?
详情:
实际上我尝试解析以下json并根据解析的json构建动态查询
{
"query":{
"where":[{
"or":[
{
"fieldName":"address1","fieldValue":"Dummy address1",
"operator":"equal"
}
],
"and":[{
"fieldName":"version","fieldValue":"1",
"operator":"equal"
}]
}
]
}
}
所以你可以建议我使用mongoTemplate spring数据将json解析成Mongodb查询的其他方法
这是我的解析代码
if(null != eventSearch.getQuery())
{
if(null != eventSearch.getQuery().getWhere() && eventSearch.getQuery().getWhere().size() > 0)
{
for (Where whereClause : eventSearch.getQuery().getWhere()) {
if(null != whereClause.getOr() && whereClause.getOr().size() > 0){
List<org.springframework.data.mongodb.core.query.Criteria> orCriterias = new ArrayList<org.springframework.data.mongodb.core.query.Criteria>(whereClause.getOr().size());
for (Field field: whereClause.getOr()) {
if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
{
orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).is(field.getFieldValue()));
}else if(field.getOperator().equalsIgnoreCase(QueryOperator.LT)){
orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).lt(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.GT)){
orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).gt(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.LTE)){
orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).lte(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.GTE)){
orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).gte(field.getFieldValue()));
}
}
query.addCriteria(new org.springframework.data.mongodb.core.query.Criteria().orOperator(orCriterias.toArray(new org.springframework.data.mongodb.core.query.Criteria[whereClause.getOr().size()])));
}
if(null != whereClause.getAnd() && whereClause.getAnd().size() > 0){
List<org.springframework.data.mongodb.core.query.Criteria> andCriterias = new ArrayList<org.springframework.data.mongodb.core.query.Criteria>(whereClause.getAnd().size());
for (Field field: whereClause.getAnd()) {
if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
{
andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).is(field.getFieldValue()));
}else if(field.getOperator().equalsIgnoreCase(QueryOperator.LT)){
andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).lt(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.GT)){
andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).gt(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.LTE)){
andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).lte(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.GTE)){
andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).gte(field.getFieldValue()));
}
}
//Getting exception at this line
query.addCriteria(new org.springframework.data.mongodb.core.query.Criteria().andOperator(andCriterias.toArray(new org.springframework.data.mongodb.core.query.Criteria[whereClause.getAnd().size()])));
}
}}
答案 0 :(得分:4)
您的代码过于苛刻,我暂时将org.springframework.data.mongodb.core.query.Criteria
替换为Criteria
。
// added
Query query = new Query();
if(null != eventSearch.getQuery())
{
if(null != eventSearch.getQuery().getWhere() && eventSearch.getQuery().getWhere().size() > 0)
{
// added
List<Criteria> wheres = new ArrayList<>();
for (Where whereClause : eventSearch.getQuery().getWhere()) {
// added
Criteria where = new Criteria();
if(null != whereClause.getOr() && whereClause.getOr().size() > 0){
List<Criteria> orCriterias = new ArrayList<Criteria>(whereClause.getOr().size());
for (Field field: whereClause.getOr()) {
if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
{
orCriterias.add(Criteria.where(field.getFieldName()).is(field.getFieldValue()));
}else if(field.getOperator().equalsIgnoreCase(QueryOperator.LT)){
orCriterias.add(Criteria.where(field.getFieldName()).lt(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.GT)){
orCriterias.add(Criteria.where(field.getFieldName()).gt(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.LTE)){
orCriterias.add(Criteria.where(field.getFieldName()).lte(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.GTE)){
orCriterias.add(Criteria.where(field.getFieldName()).gte(field.getFieldValue()));
}
}
// comment out
// query.addCriteria(new Criteria().orOperator(orCriterias.toArray(new Criteria[whereClause.getOr().size()])));
// replaced with
if (orCriterias.size() > 0) {
where.orOperator(orCriterias.toArray(new Criteria[0]));
}
}
if(null != whereClause.getAnd() && whereClause.getAnd().size() > 0){
List<Criteria> andCriterias = new ArrayList<Criteria>(whereClause.getAnd().size());
for (Field field: whereClause.getAnd()) {
if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
{
andCriterias.add(Criteria.where(field.getFieldName()).is(field.getFieldValue()));
}else if(field.getOperator().equalsIgnoreCase(QueryOperator.LT)){
andCriterias.add(Criteria.where(field.getFieldName()).lt(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.GT)){
andCriterias.add(Criteria.where(field.getFieldName()).gt(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.LTE)){
andCriterias.add(Criteria.where(field.getFieldName()).lte(field.getFieldValue()));
}
else if(field.getOperator().equalsIgnoreCase(QueryOperator.GTE)){
andCriterias.add(Criteria.where(field.getFieldName()).gte(field.getFieldValue()));
}
}
// comment out
// //Getting exception at this line
// query.addCriteria(new Criteria().andOperator(andCriterias.toArray(new Criteria[whereClause.getAnd().size()])));
// replaced with
if (andCriterias.size() > 0) {
where.andOperator(andCriterias.toArray(new Criteria[0]));
}
}
// added
wheres.add(where);
}
// added
if (wheres.size() > 0) {
query.addCriteria(new Criteria().andOperator(wheres.toArray(new Criteria[0])));
}
}
}
如果您的运营商仅包含 == != < <= > >=
,您可以尝试通过直接或间接更改JSON来缩短代码,如下所示:
{
"query":{
"where":[{
"or":[
{
"fieldName":"address1","fieldValue":"Dummy address1",
"operator":"equal"
},
{
"fieldName":"address1","fieldValue":"Dummy address2",
"operator":"$gt" // added: greater than
},
{
"fieldName":"address1","fieldValue":"Dummy address3",
"operator":"$ne" // added: not equal
}
],
"and":[{
"fieldName":"version","fieldValue":"1",
"operator":"equal"
}]
}
]
}
}
然后,部分代码可以这样写:
for (Field field: whereClause.getAnd()) {
if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
{
andCriterias.add(Criteria.where(field.getFieldName()).is(field.getFieldValue()));
} else {
andCriterias.add(Criteria.where(field.getOperator()).is(new BasicDBObject(field.getFieldName(), field.getFieldValue())));
}
}
whereClause.getOr()
与whereClause.getAnd()
类似,如果您愿意,可以将它们组合在一个循环中以缩短代码。
答案 1 :(得分:1)
我无法真正帮助您解析代码,但您可以使用
从内层构建查询DBObject conditions = new BasicDBObject("field1",val1).append("field2",val2)...;
然后将它们与
链接在一起DBObject query = new BasicDBObject("$or",conditions);
和
DBObject query = new BasicDBObject("$and",conditions);