Zachary Tang
Zachary Tang

Reputation: 53

Morphia Query by Reference ObjectID

Here's my entity's definition:

@Entity("Comment")
public class Comment extends BaseEntity {

    @Reference
    private Merchant merchant;

    ...
}

@Entity("Merchant")
class Merchant extends BaseEntity{
    @Id
    @Property("id")
    protected ObjectId id;

    ...
}

And here's my data:

comment:{
"_id": ObjectId("546c1ac64652e5180dc21577"),
"merchant" : DBRef("Merchant", ObjectId("546c1ac64652e5180dc21576")),

...
}

When I create a Query like:

Query<Comment> query = ds.createQuery(Comment.class);
query.field("merchant").equal(new ObjectId("546c1ac64652e5180dc21576"));

commentDao.findOne(query);

There's no result returned, I'd like to ask which is the right way to query a comment data with merchant's ObjectId?

Thanks for your help.

Upvotes: 3

Views: 6890

Answers (4)

faisal00813
faisal00813

Reputation: 412

You can do with mongodb driver

        MongoClient mongo =new MongoClient(mongoURI);
        DBCollection dbCollection =mongo.getDB("<your_db>").getCollection("Comment");
        DBObject dbObject = (DBObject) JSON.parse("{ 'merchant' : { '$ref' : 'Merchant' , '$id' : { '$oid' : '5693e72244ae9fe4803a4520'}}}");

        String json=JSON.serialize(dbCollection.find(dbObject));

Note the single qoute in the json.

OR

In Morphia like:

Query q = MorphiaObject.datastore.find(Comment.class).field("merchant").equal(MorphiaObject.datastore.get(Merchant.class,new ObjectId("5693e72244ae9fe4803a4520")));

Upvotes: 0

Mariano Ruiz
Mariano Ruiz

Reputation: 4759

The correct way is to get the Merchant object with the ID, and then pass it to the Comment query:

Query<Merchant> merchantQuery = ds.createQuery(Merchant.class);
merchantQuery.field("id").equal(new ObjectId(merchantId)); 
Merchant merchant = merchantQuery.get();     // Get the Merchant object

Query<Comment> commentQuery = ds.createQuery(Comment.class);
commentQuery.filter("merchant", merchant);
commentQuery.get()                           // Get the Comment object

Upvotes: 0

xeraa
xeraa

Reputation: 10859

Query<Comment> query = ds.find(Comment.class).disableValidation()
    .field("Merchant").equal(new Key<>(Merchant.class, merchantId);

I think you need to disable validation, otherwise you'll see some rather unnecessary warning.

You can query the DBRef ID directly, but since DBRef itself is typed, I'd not circumvent it unless you have some valid reason.

Upvotes: 3

Nic Cottrell
Nic Cottrell

Reputation: 9695

I don't like the way that Morphia uses DBRef when it could easily use just ObjectId (but the DBRef does contain the class name allowing you to subclass Merchant).

Anyway, you should be able to do:

Query<Comment> query = ds.createQuery(Comment.class);
query.field("merchant.$id").equal(new ObjectId("546c1ac64652e5180dc21576")

or with pure Java driver

collection.find(new BasicDBObject("merchant",
    new BasicDBObject("$ref", "Merchant")
      .append("$id", new ObjectId("546c1ac64652e5180dc21576"))))

Upvotes: 1

Related Questions