Question

I need to hide all the user related data whose isActive flag is set to false. There are many collection in which I have used user collection as of type DBRef (around 14 collections) and each collection contains more than 10 million records.

Let me explain it more properly with help of example.

Suppose I have two collections:

  1. User
  2. Contact

User collection contains following fields:

  1. Firstname (String)
  2. Last Name (String)
  3. isActive (Boolean)

Contact collection contains following fields:

  1. Contacter (User) Declared as of type DBref.
  2. Contactee (User) Declared as of type DBRef.
  3. ContactStatus (String)

Now I want to fire a query which will fetch all the contacts whose ContactStatus = "Confirmed" && Contacter.isActive = true && Contactee.isActive = true

In terms of mongodb, the query will be something like this:

db.Contacts.find({"ContactStatus" : "Confirmed", "Contacter.isActive" : true, "Contactee.isActive" : true});

But when I run this query in mongo shell, it always returns a zero record.

So the question here is 1) Is it possible to fire a query on the DBRef's inner field ? 2) If not, then how can I achieve that.

Note - At this stage, I am not able to modify my data model. With the help of "in" query, I can achieve this. But it will ultimately increase one round trip everywhere where I need to hide that user.

Currently I am using mongodb-2.4.5 and Spring-Data-MongoDB-1.2.3 jar

So far my code is like this -

Criteria criteria = new Criteria();
criteria = criteria.where(Contact.CONTACT_REQUEST_STATUS).is(ContactRequestStatusEnum.ACCEPTED);
criteria = criteria.and(Contact.CONTACTER + "." + User.ACTIVE).is(Boolean.TRUE);
criteria = criteria.and(Contact.CONTACTEE + "." + User.ACTIVE).is(Boolean.TRUE);

Query q = new Query(criteria);
List<Contact> contacts = Contacts.find(q, Contact.class);
Was it helpful?

Solution

Yes, you can query on the DbRef fields, but not the way you are doing it.

DbRef is a small sub-documents which contains two fields:

$ref -the referenced collection

$id - the _id value of a document in that referenced collection

(actually there is a third field $db if the reference is to a different db)

So, using the shell you can only ask for contacter.$id (which returns the Object id in users collection) or $ref, but you can't query on something such as contract.isActive, as this is a field of the user, not the Ref, and the shell doesn't fetch the user.

If you are using java driver, both Contacter and Contactee are represented as com.mongodb.DBRef which has a method fetch() to retrieve the DBObject (user)

If using spring-data-mongodb, you might want to have class such as:

class Contact {

@DBRef
User contacter; 

@DBRef
User contactee;

String contactStatus; 

}

Both user objects will be loaded for you

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top