1

I want to query all the UserGroup's ID where admins's ID="25160228446835585906563830293" or users's ID ="25160228446835585906563830293".

this is a hashmap key and value pair in java obj hashmap<String,Date> "25160228446835585906563830293" : ISODate("2013-03-26T04:51:36.731Z")

{ "_id" : ObjectId("51512958849ca4748271c640"), 
  "_class" : "com.pcd.app.model.UserGroup", 
  "groupName" : "sdfsadfsad", 
  "privacyType" : "PRIVACY_OPEN", 
  "approvalType" : "MEMBER_APPROVAL", 
  "groupDescription" : "test", 
  "admins" : { 
      "25160228446835585906563830293" : ISODate("2013-03-26T04:51:36.731Z"),
      "25160228446835585906563830294" : ISODate("2013-03-26T04:51:36.731Z"),
      "25160228446835585906563830295" : ISODate("2013-03-26T04:51:36.731Z") 
  },
  "users" : { 
      "25160228446835585906563830296" : ISODate("2013-03-26T04:51:36.731Z") 
  } 
}
2
  • Ok, so what have you tried? Fyi: It will need to scan through all documents if the keys aren't fixed and indexed. Commented Mar 26, 2013 at 11:05
  • I am totally new to mongodb or any NoSql db, so can I index the middle of "string"? in java obj, i know it is a key but how does the mongodb knows that is a key? Commented Mar 26, 2013 at 16:35

2 Answers 2

6

I'd suggest you restructure your document to make it indexable and more easily searched in MongoDB.

Instead of using the id of the admin as a field, add each admin as an object of an array:

    "admins" : [
        { id: "25160228446835585906563830293",
           date: ISODate("2013-03-26T04:51:36.731Z") }
     ],

This will make searches more natural:

db.so.find( { "admins.id" : 
    { $in: ['25160228446835585906563830293', 
            '25160228446835585906563830296']}})

You can use the $in (docs) operator to look for admins with an id that matches the list as you wanted (admins.id).

So, given a Java QueryBuilder, it might look something like this:

BasicDBList adminIds = new BasicDBList();
adminIds.addAll(ids); // the ids could be a List<String> 
DBObject inClause = new BasicDBObject("$in", adminIds);
DBObject query = new BasicDBObject("admins.id", inClause);

You may want to use ensureIndex to build an index (docs).

Based on your original example, here's the full document for reference:

{ 
    "_id" : ObjectId("51512958849ca4748271c640"), 
    "_class" : "com.pcd.app.model.UserGroup", 
    "groupName" : "sdfsadfsad", 
    "privacyType" : "PRIVACY_OPEN", 
    "approvalType" : "MEMBER_APPROVAL", 
    "groupDescription" : "test", 
    "admins" : [
        { id: "25160228446835585906563830293" ,
          date: ISODate("2013-03-26T04:51:36.731Z") },
        { id: "25160228446835585906563830294" , 
          date:  ISODate("2013-03-26T04:51:36.731Z") },
        { id: "25160228446835585906563830295" , 
          date: ISODate("2013-03-26T04:51:36.731Z") } 
    ],
    "users" : [
        { id: "25160228446835585906563830296", 
          date : ISODate("2013-03-26T04:51:36.731Z") }
    ]
}
Sign up to request clarification or add additional context in comments.

3 Comments

thanks for the help, I will have to look into it how to make my own custom converter for the spring data.
What if I want to upsert into the admin field? For example, I want to edit the date or add a new admin field with the date if the admin doesn't already exist?
@Ryan_DS-please ask a new question. This answer is nearly 7 years old.
0

If you are using mongodb java driver you can do the following:

   BasicDBObject queryForAdminsID = new BasicDBObject("admins." + adminsID, new BasicDBObject("$exists", true));  
// BasicDBObject queryForUsersID = new BasicDBObject("users." + usersID, new BasicDBObject("$exists", true));
cursor = coll.find(query); // coll is a DBCollection

try {
while(cursor.hasNext()) {
   System.out.println(cursor.next());
}
} finally {
 cursor.close();
}

where usersID and adminsID are your ids

4 Comments

Ok but what about I want to query, 25160228446835585906563830293 from the one column? "admins" : { "25160228446835585906563830293" : ISODate("2013-03-26T04:51:36.731Z"), "25160228446835585906563830294" : ISODate("2013-03-26T04:51:36.731Z"), "25160228446835585906563830295" : ISODate("2013-03-26T04:51:36.731Z") }
then you should define adminsID as following and pass to the code above. It will return you whole data back. String adminsID = "25160228446835585906563830293"
Ok thanks, will try that, so is that possible to use one query instead of two? for admins and users in one query?
I did only single queries before, but you can try to add them into a single BasicDBObject and then try to query it.. But then it will be an AND query, not OR

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.