动态地从json字符串创建和读取树数据结构

时间:2012-07-31 05:36:22

标签: java json lucene jettison

我正在尝试开发动态查询构建器好几天。但我在构建它时遇到了问题。

我正在复兴的是像这样的json。

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

这是以可读的方式

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] => 
                                )

                        )

                )

        )

)
  • 这个json可以根据用户输入进行更改(可以有更多深度 或更少)。
  • 我要做的是为apache创建一个搜索查询 lucene ...(暂时假设叶子值正好 字符串。)

必须这样的东西(我需要的东西)

  

(年份:另一个值OR(报告:一些valeus和引用:一些valeues))

我尝试使用Jettison库并使用DefaultMutableTreeNode来创建树结构。但它没有像我预期的那样工作。然后我尝试了whit递归函数,它也没有用

我想是否有可能创造这种东西。如果是的话怎么做。

非常感谢您的尝试! 提前谢谢。

3 个答案:

答案 0 :(得分:2)

好了现在需求很明确,这是解决方案

定义您的操作

enum MyOperator {

  AND,
  OR

}

写一个类来保存原子操作

class AtomicOperation {

   Object lhs;
   Object rhs;
   MyOperator operator;

}

现在,如果你想要类似的东西 (年份:另一个值OR(报告:一些valeus和引用:一些valeues))

您的JSON应如下所示:

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

首先将此JSON转换为AtominOperation类 使用代码

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;

    }

最终的AtomicOperation对象将是你想要的。 :)

答案 1 :(得分:1)

您查询的JSON字符串

确定。这就是我的尝试。

(年份:另一个值OR(报告:一些valeus和引用:一些valeues和Field:另一个))

应该是这样的:

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"}

如果MYOperator枚举是:

public enum MyOperator {

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

}

和AtomicOperation是

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() + ")"; 
}

}

然后,您可以使用以下代码构建必要的AtomicOperation对象

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

下面是完整的ConvertJsonToObject类

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);
    }
}

答案 2 :(得分:0)

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);