Given items: [{ prop1 : "a", prop2 : "b" , prop3, "c",....},....]
and patterns: [{ prop1 : "a", prop2 : "Any"},...]
I want to create a query to find all patterns that match the given items.
The resulting query is of form:
((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))
....
I've tried to build a DSL-form , but I get an ambiguous implicit error on the init:
Can this notation be used? Or how could I implement this with DBObject.Builder or MongoDbObjects?
Thanks, Eli
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
})
The $or
and $and
parts of the dsl require a traversable and can't initiated without one - hence the compile error.
If you can just delay the creation of the $and
and $or
parts of the query until you have built the traversable it works:
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)
This returns the following output:
{"$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"}]}]}]}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.