0

I'm creating a find method that receives an object and for each attribute that is not null, i need to set his value on MongoDBObject. I'm having problems to use $in operator.

Here is what i'm trying to do:

def findRooms(room:Room) = {
    val query = MongoDBObject.newBuilder
    if(room.id != null && !room.id.isEmpty)
      query+=("_id" -> room.id)
    if(room.members != null && room.members.length > 0)
      //Here i try to create a list to search inside the array
      query+"members" $in List[MongoDBObject](room.members.map(mongoDBObject => 
             parseUser(mongoDBObject)))
    val result = roomCollection.find(query.result)
    ....
}

A example of my json inside mongodb is:

{
  "_id" : ObjectId("54bfccc92850e17166991765"),
  "name" : "room1",
  "members" : [{
      "user" : {
        "phoneNumber" : "12378954"
      }
    }, {
      "user" : {
        "email" : "test@google.com",
        "phoneNumber" : "1010"
      }
    }]
}


{
  "_id" : ObjectId("54bfccfb285033b1d718bc87"),
  "name" : "room2",
  "members" : [{
      "user" : {
        "phoneNumber" : "98476541"
      }
    }, {
      "user" : {
        "email" : "test@google.com",
        "phoneNumber" : "1010"
      }
    }]
}

I would like to search for all documents that have the following users inside the array:

{ user: { "phonenumber" : "12378954" }} and { user: { "email": "test@google.com", "phonenumber" : "1010" }}**

How can i use the query+="members" in ... What object should i make to perform this search?

Thank in advance.

Edit:

if(room.members != null && room.members.length > 0){
  val emails = scala.collection.mutable.MutableList[String]()
  val phones = scala.collection.mutable.MutableList[String]()
  val forwardUris = scala.collection.mutable.MutableList[String]()
  for(member <- room.members){
    if(member.email != null && member.email != None)
      emails+=member.email.get
    if(member.forwardUrl != null && member.forwardUrl != None)
      forwardUris+=member.forwardUrl.get
    if(member.phoneNumber != null && member.phoneNumber != None)
      phones+=member.phoneNumber.get
  }

  if(emails.length > 0)
    query+=("members.user.email" -> MongoDBObject("$all" -> emails))

  if(phones.length > 0)
    query+=("members.user.phoneNumber" -> MongoDBObject("$all" -> phones))

  if(forwardUris.length > 0)
    query+=("members.user.forwardUrl" -> MongoDBObject("$all" -> forwardUris))
}

1 Answers1

0

You'll need to use the $all operator when querying arrays to only match documents where all items exist in the array. Then to query against a nested item in mongodb you need to use dot notation

So in the shell you'd run:

db.test.find({"members.user.phoneNumber" : {$all: ["12378954", "1010"]}, 
              "members.user.email": "test@google.com"})

In Casbah that would be:

val query: DBObject = MongoDBObject("members.user.phoneNumber" -> MongoDBObject("$all" -> List("12378954", "1010"), 
                                    "members.user.email" -> "test@google.com"))
roomCollection.find(query)

Or you could use the DSL:

("members.user.phoneNumber" $all ("1", "2")) ++ 
MongoDBObject("members.user.email" -> "test@google.com")
Ross
  • 17,861
  • 2
  • 55
  • 73
  • but i don't know what i have in array..i only know that is a json of "user" type but i don't know what fields the user has ( no one is mandatory ). I think that i got, let me try something! –  Jan 21 '15 at 17:55
  • If i run it on shell, it works but it's not working on Casbah. I've just copy and paste..but no work –  Jan 21 '15 at 18:28