2015-05-11 46 views
0

鑑於項目:[{ prop1 : "a", prop2 : "b" , prop3, "c",....},....] 和模式:[{ prop1 : "a", prop2 : "Any"},...]

我想創建一個查詢來查找匹配給定的項目,所有的模式。

結果查詢是形式:

((A or B or C) AND (D or E or F) AND (G or H or J)) 
or 
((A or B or C) AND (D or E or F) AND (G or H or J)) 
or 
((A or B or C) AND (D or E or F) AND (G or H or J)) 
.... 

我試圖建立一個DSL-形式,但我上初始化一個模糊的隱含錯誤:

可這個符號可以使用?或者我怎麼能用DBObject.Builder或MongoDbObjects實現這個?

感謝, 禮

import com.mongodb.casbah.query.Imports._ 

/* test data */ 
val thing1 = Map[String,String]("thing_type" -> "PC", "os"-> "Windows", "vendor"-> "lenova") 
val thing2 = Map[String,String]("thing_type" -> "Tablet", "os"-> "iOS", "vendor"-> "Apple") 
" 

val things_list = List(thing1, thing2) 
/* end test data */ 

val atts_for_search = List("thing_type", "os", "vendor") 
var pattern_query = $or()      // *causes a compilation error 
things_list.foreach (thing => { 
    var att_and_list = $and()    // *causes a compilation error 
    atts_for_search.foreach (att => { 
      att_and_list ++= $or(att $eq thing(att),att $exists false,att $eq "Any") 

    }) // foreach attribute 
    pattern_query ++= att_and_list 
}) 

回答

0

$or$and部分的DSL需要穿越的,沒有一個人不能啓動 - 因此編譯錯誤。

如果你可以延遲$and$or部分查詢的創建,直到你已經把它的工作原理可穿越:

import com.mongodb.casbah.query.Imports._ 

/* test data */ 
val thing1 = Map[String,String]("thing_type" -> "PC", "os"-> "Windows", "vendor"-> "lenova") 
val thing2 = Map[String,String]("thing_type" -> "Tablet", "os"-> "iOS", "vendor"-> "Apple") 
val things_list = List(thing1, thing2) 
/* end test data */ 

val atts_for_search = List("thing_type", "os", "vendor") 
val ors = scala.collection.mutable.ListBuffer[DBObject]() 
things_list.foreach (thing => { 
    var ands = scala.collection.mutable.ListBuffer[DBObject]() 
    atts_for_search.foreach (att => { 
      ands += $or(att $eq thing(att),att $exists false,att $eq "Any") 

    }) // foreach attribute 
    ands += $and(ands) 
}) 
val pattern_query = $or(ors) 

這將返回以下輸出:

{"$or": [{ "$and": [{ "$or": [ { "thing_type" : "PC"} , { "thing_type" : { "$exists" : false}} , { "thing_type" : "Any"}]} , 
        { "$or": [ { "os" : "Windows"} , { "os" : { "$exists" : false}} , { "os" : "Any"}]} , 
        { "$or": [ { "vendor" : "lenova"} , { "vendor" : { "$exists" : false}} , { "vendor" : "Any"}]}]} , 
     { "$and": [{ "$or": [ { "thing_type" : "Tablet"} , { "thing_type" : { "$exists" : false}} , { "thing_type" : "Any"}]} , 
        { "$or": [ { "os" : "iOS"} , { "os" : { "$exists" : false}} , { "os" : "Any"}]} , 
        { "$or": [ { "vendor" : "Apple"} , { "vendor" : { "$exists" : false}} , { "vendor" : "Any"}]}]}]}