问题描述:

I'm trying to develop a dynamic query builder for days. But I'm having a problem with building it.

What I'm reviving is a json like this.

{"category":"Case Law","query":{"AND":{"Year":{"having":"","exact":"","any":"","none":""},"AND":{"Report":{"having":"","exact":"","any":"","none":""},"Citation":{"having":"","exact":"","any":"","none":""}}}}}

Here is it in much readable way

Array

(

[category] => Case Law

[query] => Array

(

[OR] => Array

(

[Year] => Array

(

[having] => some

[exact] => values

[any] => might

[none] => have

)

[AND] => Array

(

[Report] => Array

(

[having] =>

[exact] =>

[any] =>

[none] =>

)

[Citation] => Array

(

[having] =>

[exact] =>

[any] =>

[none] =>

)

)

)

)

)

  • this json can change according to the user inputs(can have more depth

    or less).

  • what I'm trying to do is create a search query for apache

    lucene...(for the moment lets assume that leaf values are just

    strings.)

It must be something like this(What I need)

(Year:another values OR (Report:some valeus AND Citation:some valeues))

I tried with Jettison library and used DefaultMutableTreeNode to create the tree structure . But it didn't work as I expected.Then i tried whit recursive functions and it also didn't worked

I want to is it possible to create this kind of thing. If yes how to do.

Your attempt is highly appreciated!

Thanks in advance.

网友答案:

The JSON String for you query

Ok. This is what i tried.

(Year:another values OR (Report:some valeus AND Citation:some valeues AND Field: another))

should be something like :

String json = 
{"lhs":{"lhs":{"lhs":{"lhs":"Field","rhs":"Value","operator":"EQUAL_TO"},"rhs":{"lhs":"Citation","rhs":"Citation","operator":"EQUAL_TO"},"operator":"AND"},"rhs":{"lhs":"Report","rhs":"Report1","operator":"EQUAL_TO"},"operator":"AND"},"rhs":{"lhs":"Year","rhs":"2001","operator":"EQUAL_TO"},"operator":"OR"}

if The MYOperator enum is :

public enum MyOperator {

    AND,
    OR,
    EQUAL_TO {
    @Override
    public String toString() {
        return ":";
    }
},
    IN

}

and AtomicOperation Is

public class AtomicOperation {


     Object lhs;
     Object rhs;
     MyOperator operator;

     AtomicOperation(Object lhs,MyOperator operator, Object rhs) {
         this.lhs = lhs;
         this.rhs = rhs;
         this.operator = operator;
     }

    public Object getLhs() {
        return lhs;
    }
    public void setLhs(Object lhs) {
        this.lhs = lhs;
    }
    public Object getRhs() {
        return rhs;
    }
    public void setRhs(Object rhs) {
        this.rhs = rhs;
    }
    public MyOperator getOperator() {
        return operator;
    }
    public void setOperator(MyOperator operator) {
        this.operator = operator;
    }

     @Override
public String toString() {
        return "(" + lhs.toString() + " " + operator.toString() + " " + rhs.toString() + ")"; 
}

}

Then You can Build the necessary AtomicOperation Object using the below code

AtomicOperation _r = deriveFromJSON(ConvertJsonToObject.getFromJSON(json,AtomicOperation.class));

Below is the complete ConvertJsonToObject class

public class ConvertJsonToObject {

    private static Gson gson = new GsonBuilder().create();

    public static final <T> T getFromJSON(String json, Class<T> clazz) {
        return gson.fromJson(json, clazz);
    }

    public static final <T> String toJSON(T clazz) {
        return gson.toJson(clazz);
    }
}
网友答案:

Ok Now the requirement is clear and here is the solution

define your operations

enum MyOperator {

  AND,
  OR

}

Write a class to hold you atomic operaton

class AtomicOperation {

   Object lhs;
   Object rhs;
   MyOperator operator;

}

Now if You want something like (Year:another values OR (Report:some valeus AND Citation:some valeues))

your JSON should look like :

String jsonString = {{Year:['2001','2002']} OR {{Report:['Report1']} AND {Citation:['Citation1']}}}

So First Cast this JSON to AtominOperation class using the code

ConvertJsonToObject.getFromJSON(jsonString,AtominOperation.class);

GSON will cast it to a Simple AtominOperation Object with operation "OR"
and lhs,rhs as 2 LinkedHashMaps (Default behaviour of GSON)

Now use the below method to get the proper AtomicOperation Object from the
above AtomicOperation Object.

public static AtomicOperation deriveFromJSON(AtomicOperation operation) {

        if (operation.getLhs().getClass().equals(LinkedHashMap.class)) {
            AtomicOperation leftOperation = deriveFromJSON(ConvertJsonToObject
                    .getFromJSON(ConvertJsonToObject.toJSON(operation.getLhs()),
                            AtomicOperation.class));
            AtomicOperation rightOperation = deriveFromJSON(ConvertJsonToObject
                    .getFromJSON(ConvertJsonToObject.toJSON(operation.getRhs()),
                            AtomicOperation.class));
            return new AtomicOperation(leftOperation, operation.getOperator(),
                    rightOperation);
        }
        return operation;

    }

The Final AtomicOperation Object would be what u want. :)

网友答案:
Use Something like Google Gson

class ConvertJsonToObject {

    private static Gson gson = new GsonBuilder().create();

    public static final <T> T getFromJSON(String json, Class<T> clazz) {
        return gson.fromJson(json, clazz);
    }

}

String jsonString = "{"category":"Case Law","query":{"AND":{"Year the case was instituted":{"having":"","exact":"","any":"","none":""},"AND":{"Report":{"having":"","exact":"","any":"","none":""},"Citation":{"having":"","exact":"","any":"","none":""}}}}}
"

Now you can use ConvertJsonToObject.getFromJSON(jsonString,Map.class);
相关阅读:
Top