2012-04-11 4 views
0

Ich möchte auf mehrere Filter auf Basis Attribute abzufragen und die Kriterien dynamischIteration dynamisch Kriterien bauen Block-

Domain Class 
PatientAttr { 
    def name 
    def value 
} 

Kriterien Bauordnung

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) 
       } 
      } 
     } 

Was ich finde, ist, dass nur die letzte bauen "und" Aussage der Liste wird ausgewertet. Ermöglicht der Kriteriengenerator das dynamische Erstellen von Kriterien?

Der obige Code sollte

 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 
      } 
     } 

Antwort

1

zu diesem gleichwertig sein, weiß ich nicht, warum Sie Probleme haben, aber da die Standard-Verbindung für Abfragen and ist, gibt es keinen Grund, eine and{} Verschluss zu verwenden, in Ihr Beispiel überhaupt. Ihre Anfrage oben ist die gleiche wie:

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 
    } 

Wenn Sie die Top-leve Artikel wollen or d zusammen‘, dann müssen Sie den äußeren Block in einem or{} Verschluss wickeln:

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) 
       } 
      } 
     } 
    } 

Dieser Wille Rückkehr eine Abfrage mit den Ergebnissen wie:

Name ist ‚Serumalbumin ...‘ und Wert größer als ‚3.5‘
OR
Name ist 'M-Spike ...' und Wert größer als 2,3
OR etc

Hoffentlich hilft.

+0

def results = { criteria.list eq 'name' "Serumalbumin (g/dL)" gt 'Wert', 3.5 als Float eq 'name', "M-Spitze (g/dL)" gt 'wert', 2,3 als Float } – nialloc

0

von Ihrem Block:

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 
     } 
    } 

meinen Sie zum Ausdruck bringen:

((name == "Serum albumin (g/dL)") or (value == 3.5)) 
and 
((name == "M-spike (g/dL)") or (value == 3.3)) 

Dann sollten Sie den Code sein:

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) 
       } 
      } 
     } 
    } 

, wenn Sie zum Ausdruck bringen bedeuten:

((name == "Serum albumin (g/dL)") and (value == 3.5)) 
and 
((name == "M-spike (g/dL)") and (value == 3.3)) 

Dann sollten Sie den Code sein:

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) 
      } 
     } 
    } 

da und ist die Standardoperation, können Sie die Methode und weglassen.