Grails 使用GPath深度遍历字符串中带有点的Groovy对象的方法

Grails 使用GPath深度遍历字符串中带有点的Groovy对象的方法,grails,mongodb,groovy,gpath,Grails,Mongodb,Groovy,Gpath,我遇到的情况是,我正在用字符串查询MongoDB,查找对象层次结构中一个以上层次的字段。此查询必须是字符串。例如,我在Groovy中查询如下内容: def queryField = 'a.b.c' //this is variable and can be different every time def result = mongodb.collection.findOne([queryField:5]) 问题是,我希望在结果中找到嵌套字段的值。有了GPath,我可以深入一层,得到a的值

我遇到的情况是,我正在用字符串查询MongoDB,查找对象层次结构中一个以上层次的字段。此查询必须是字符串。例如,我在Groovy中查询如下内容:

def queryField = 'a.b.c'  //this is variable and can be different every time
def result = mongodb.collection.findOne([queryField:5])
问题是,我希望在结果中找到嵌套字段的值。有了GPath,我可以深入一层,得到a的值

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中目前不起作用。有一个bug被记录了下来,但是我想知道是否有更好的解决方法可以用于这个场景,它比我通过在点上拆分然后构建对象遍历来解析字符串更干净。请注意,“a.b.c”是可变的,在运行时是未知的(例如,它可以是“a.b.d”)

根据bug/线程,支持虚线属性访问器似乎存在一些模糊问题。根据邮件列表线程,评估queryField字符串似乎是您的最佳选择:

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

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

邮件列表线程有点旧,所以有一个新的ish(至少是1.7.2版)Eval类可以帮助运行没有大绑定的小片段


否则,您可以拆分字符串并递归地对对象执行属性求值,从而有效地再现GPath遍历行为的子集。

我的回答的后半部分有帮助吗?谢谢@tim_yates,这正是我要找的,但从我的查询中一直找不到。在您介绍的两种方法(eval和string解析)中,您推荐哪一种。两者都在进行字符串解析,但我认为评估可能会慢一点。有什么想法吗?我会选择inject方法,不过如果属性中有点,比如:
a.“some.var”.c
Ack,我没有看到@tim_yates使用同一个Eval类的评论。