![](/img/trans.png)
[英]MongoDB Aggregation - How can i apply query expression into match stage using spring-data-mongodb?
[英]How can i add or & and Criteria clauses with in a single Query Object Mongodb Spring data
我想同時向我的查詢對象添加or&和子句,但我一直在錯誤以下得到提示
由於com.mongodb.BasicDBObject的限制,您不能添加第二個“空”條件嗎?
例如
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()])));
}
}}
您的代碼太笨拙,我暫時將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()
那么你可以在一個周期內將它們結合起來,以縮短代碼,如果你想要的。
我無法真正為您提供解析代碼,但是您可以通過使用以下內容從內部構建查詢
DBObject conditions = new BasicDBObject("field1",val1).append("field2",val2)...;
然后將它們與
DBObject query = new BasicDBObject("$or",conditions);
和
DBObject query = new BasicDBObject("$and",conditions);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.