2012-02-07 9 views
4

私は、オブジェクト階層の2つ以上のレベルのフィールドの文字列をMongoDBに照会しているという状況です。このクエリは文字列でなければなりません。だから、例えば私はGroovyでこのような何かを照会しています:GPathを使用してGroovyオブジェクトを文字列のドットで深くトラバースする

def queryField = 'a.b.c' //this is variable and can be different every time 
def result = mongodb.collection.findOne([queryField:5]) 

問題は何も結果に私は、ネストされたフィールドの値を検索することを生じません。 GPathと私は1つのレベル深く行くと、これは

def aObj = result."a" //or result["a"] 

しかし、私はこのような何かを行うことによってより深くに行きたいことの価値を得ることができます:

def queryField = "a.b.c"  //this can change every time and is not always 'a.b.c' 
def cObj = result[queryField] //since field is variable, can't just assume result.a.b.c 

これが今Groovyでは動作しません。 。 hereのログに記録されたバグがありましたが、このシナリオでは、ドットを分割してオブジェクトのトラバーサルを構築して文字列を解析するよりもはるかに優れた回避策があるかどうか疑問に思っていました。 「a.b.c」は可変であり、実行時には不明であることに注意してください(例:「a.b.d」)。

+1

私の答えの後半は役に立ちますか? http://stackoverflow.com/a/6364388/6509 –

+0

ありがとうございます@tim_yatesは、私が探していたものですが、私のクエリからそれを見つけることができませんでした。 (evalと文字列解析)をお勧めします。両方とも文字列解析を行っていますが、評価が遅いと思うでしょう。何かご意見は? – Scott

+0

私は注射方法に行きたいと思いますが、ドットがついたプロパティーは以下のように弾力性はありません: 'a.'ome.var'.c' –

答えて

2

バグ/スレッドに基づいて、点在するプロパティアクセサーをサポートする際のあいまいさの問題があります。

def result = [a: [b: [c: 42]]] 
def queryString = 'a.b.c' 

def evalResult = Eval.x(result, 'x.' + queryString) 
assert evalResult == 42 

Script on Groovy Web Console

メーリングリストのスレッドが少し古いので、新しいっぽいが(時以降があります:メーリングリストに基づいて、QUERYFIELD文字列を評価すると、あなたの最善の策だろうと思われるスレッド少なくとも1.7.2)大きなバインディングを持たない小さなスニペットを実行するのに役立つEvalクラス。

それ以外の場合は、文字列を分割して再帰的にオブジェクトのプロパティ評価を行い、GPathトラバーサル動作のサブセットを効果的に再現することができます。

+0

Ack、@tim_yatesからのコメントは表示されませんでした同じEvalクラス –

関連する問題