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 の検索クエリを作成することです... (今のところ、葉の値は単なる文字列であると仮定しましょう。)

このようなものでなければなりません(私が必要なもの)

(年:別の値 OR (レポート:いくつかの値 AND 引用:いくつかの値))

Jettison ライブラリを試し、DefaultMutableTreeNode を使用してツリー構造を作成しました。しかし、期待どおりに機能しませんでした。次に、再帰関数を試してみましたが、機能しませんでした

こういうものが作れるようになりたい。はいの場合、どうすればよいですか。

あなたの試みは大歓迎です!前もって感謝します。

4

3 に答える 3

2

さて、要件は明確になりました。ここに解決策があります

操作を定義する

enum MyOperator {

  AND,
  OR

}

アトミック操作を保持するクラスを作成する

class AtomicOperation {

   Object lhs;
   Object rhs;
   MyOperator operator;

}

(Year:another values OR (Report:some valeus AND Citation:some 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;

    }

Final AtomicOperation オブジェクトは、あなたが望むものです。:)

于 2012-07-31T07:05:16.067 に答える
1

クエリ用のJSON文字列

Ok。これは私が試したものです。

(年:別の値OR(レポート:いくつかのvaleus AND引用:いくつかのvaleues ANDフィールド:another))

次のようなものにする必要があります:

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);
    }
}
于 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 に答える