1

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

我正在复兴的是这样的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 创建一个搜索查询......(目前让我们假设叶值只是字符串。)

必须是这样的(我需要什么)

(年份:另一个值或(报告:一些价值和引用:一些价值))

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

我想有没有可能创造出这种东西。如果是怎么办。

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

4

3 回答 3

2

好的现在要求很明确,这是解决方案

定义您的操作

enum MyOperator {

  AND,
  OR

}

写一个类来保存你的原子操作

class AtomicOperation {

   Object lhs;
   Object rhs;
   MyOperator operator;

}

现在,如果您想要类似(年份:另一个值或(报告:一些价值和引文:一些价值))

您的 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 对象将是您想要的。:)

于 2012-07-31T07:05:16.067 回答
1

您查询的 JSON 字符串

行。这是我尝试过的。

(年份:另一个值或(报告:一些值和引用:一些值和字段:另一个))

应该是这样的:

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

}

和原子操作是

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);
    }
}
于 2012-07-31T12:15:38.050 回答
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);
于 2012-07-31T05:49:01.737 回答