Mongodb 使用迭代动态构建标准块

Mongodb 使用迭代动态构建标准块,mongodb,grails,gorm,Mongodb,Grails,Gorm,我想根据几个过滤器查询属性,并动态地构建条件 Domain Class PatientAttr { def name def value } 标准建筑规范 if(filters.size() != 0 ){ def criteria = PatientAttr.createCriteria() def results = criteria.list{ for (item in filters){

我想根据几个过滤器查询属性,并动态地构建条件

Domain Class
PatientAttr {
   def name
   def value
}
标准建筑规范

    if(filters.size() != 0 ){
        def criteria =  PatientAttr.createCriteria()
        def results = criteria.list{
            for (item in filters){
                def name = item.name
                def filter = item.filter
                and{
                    eq 'name', name
                    if(filter[0] == "lt")
                        lt ('value', filter[1] as Double)
                    else if(filter[0] == "gt")
                        gt ('value', filter[1] as Double)
                    else 
                        between ('value', filter[0] as Double, filter[1] as Double)
                }
            }
        } 
我发现只有列表的最后一个“and”语句被评估。criteria builder是否允许您动态生成条件

上述代码应与此等效

        def results = criteria.list{
            and{
                eq 'name', "Serum albumin (g/dL)"
                gt 'value', 3.5 as Float
            }
            and{    
                eq 'name', "M-spike (g/dL)"
                gt 'value', 2.3 as Float
            }
        }

我不知道您为什么会遇到问题,但是由于查询的默认连词是
,因此在您的示例中根本没有理由使用
和{}
闭包。您的上述查询与以下内容相同:

    def results = criteria.list{
        eq 'name', "Serum albumin (g/dL)"
        gt 'value', 3.5 as Float
        eq 'name', "M-spike (g/dL)"
        gt 'value', 2.3 as Float
    }
如果要将顶层项目
'd组合在一起,则需要将外部块包装在
或{}
闭包中:

if(filters.size() != 0 ){
    def criteria =  PatientAttr.createCriteria()
    def results = criteria.list{
        or{
            for (item in filters){
                def name = item.name
                def filter = item.filter
                and{
                    eq 'name', name
                    if(filter[0] == "lt")
                        lt ('value', filter[1] as Double)
                    else if(filter[0] == "gt")
                        gt ('value', filter[1] as Double)
                    else 
                        between ('value', filter[0] as Double, filter[1] as Double)
                }
            }
        }
    } 
这将返回一个查询,结果如下:

名称为“血清白蛋白…”,值大于“3.5”

名称为“M-spike…”且值大于2.3
或等

希望这能有所帮助。

在你的街区:

    def results = criteria.list{
        and{
            eq 'name', "Serum albumin (g/dL)"
            gt 'value', 3.5 as Float
        }
        and{    
            eq 'name', "M-spike (g/dL)"
            gt 'value', 2.3 as Float
        }
    }
你的意思是说:

((name == "Serum albumin (g/dL)") or (value == 3.5))
and
((name == "M-spike (g/dL)") or (value == 3.3))
((name == "Serum albumin (g/dL)") and (value == 3.5))
and
((name == "M-spike (g/dL)") and (value == 3.3))
那么您的代码应该是:

if(filters.size() != 0 ){
    def criteria =  PatientAttr.createCriteria()
    def results = criteria.list{
        and{
            for (item in filters){
                def name = item.name
                def filter = item.filter
                or {
                    eq 'name', name
                    if(filter[0] == "lt")
                        lt ('value', filter[1] as Double)
                    else if(filter[0] == "gt")
                        gt ('value', filter[1] as Double)
                    else 
                        between ('value', filter[0] as Double, filter[1] as Double)
                }
            }
        }
    } 
if(filters.size() != 0 ){
    def criteria =  PatientAttr.createCriteria()
    def results = criteria.list{
        and{
            for (item in filters){
                def name = item.name
                def filter = item.filter
                eq 'name', name
                if(filter[0] == "lt")
                    lt ('value', filter[1] as Double)
                else if(filter[0] == "gt")
                    gt ('value', filter[1] as Double)
                else 
                    between ('value', filter[0] as Double, filter[1] as Double)
            }
        }
    } 
如果你想表达:

((name == "Serum albumin (g/dL)") or (value == 3.5))
and
((name == "M-spike (g/dL)") or (value == 3.3))
((name == "Serum albumin (g/dL)") and (value == 3.5))
and
((name == "M-spike (g/dL)") and (value == 3.3))
那么您的代码应该是:

if(filters.size() != 0 ){
    def criteria =  PatientAttr.createCriteria()
    def results = criteria.list{
        and{
            for (item in filters){
                def name = item.name
                def filter = item.filter
                or {
                    eq 'name', name
                    if(filter[0] == "lt")
                        lt ('value', filter[1] as Double)
                    else if(filter[0] == "gt")
                        gt ('value', filter[1] as Double)
                    else 
                        between ('value', filter[0] as Double, filter[1] as Double)
                }
            }
        }
    } 
if(filters.size() != 0 ){
    def criteria =  PatientAttr.createCriteria()
    def results = criteria.list{
        and{
            for (item in filters){
                def name = item.name
                def filter = item.filter
                eq 'name', name
                if(filter[0] == "lt")
                    lt ('value', filter[1] as Double)
                else if(filter[0] == "gt")
                    gt ('value', filter[1] as Double)
                else 
                    between ('value', filter[0] as Double, filter[1] as Double)
            }
        }
    } 

由于and是默认操作,您可以省略and方法。

def results=CRITIES。列出{eq'名称',“血清白蛋白(g/dL)”gt'值,3.5为浮动eq'名称',“M-spike(g/dL)”gt'值,2.3为浮动}