1

I am trying to reproduce the classic blog schema of one Post to many Comments using Morphia and the Play Framework.

My schema in Mongo is:

{ "_id" : ObjectId("4d941c960c68c4e20d6a9abf"), 
 "className" : "models.Post", 
  "title" : "An amazing blog post", 
  "comments" : [
    {
        "commentDate" : NumberLong("1301552278491"),
        "commenter" : {
            "$ref" : "SiteUser",
            "$id" : ObjectId("4d941c960c68c4e20c6a9abf")
        },
        "comment" : "What a blog post!"
    },
    {
        "commentDate" : NumberLong("1301552278492"),
        "commenter" : {
            "$ref" : "SiteUser",
            "$id" : ObjectId("4d941c960c68c4e20c6a9abf")
        },
        "comment" : "This is another comment"
    }
]}

I am trying to introduce a social networking aspect to the blog, so I would like to be able to provide on a SiteUser's homepage the last X comments by that SiteUser's friends, across all posts.

My models are as follows:

@Entity
public class Post extends Model {

    public String title;

    @Embedded
    public List<Comment> comments;

}

@Embedded
public class Comment extends Model {

    public long commentDate;

    public String comment;

    @Reference
    public SiteUser commenter;

}

From what I have read elsewhere, I think I need to run the following against the database (where [a, b, c] represents the SiteUsers) :

db.posts.find( { "comments.commenter" : {$in: [a, b, c]}} )

I have a List<SiteUser> to pass in to Morphia for the filtering, but I don't know how to

  1. set up an index on Post for Comments.commenter from within Morphia
  2. actually build the above query
Community
  • 1
  • 1
Rich
  • 15,602
  • 15
  • 79
  • 126

1 Answers1

1
  1. Either put @Indexes(@Index("comments.commenter")) on the Post class, or @Indexed on the commenter field of the Comment class (Morphia's Datastore.ensureIndexes() will recurse in the classes and correctly create the comments.commenter index on the Post collection)

  2. I think ds.find(Post.class, "comments.commenter in", users) would work, ds being a Datastore and users your List<SiteUser> (I don't use @Reference though, so I can't confirm; you might have to first extract the list of their Keys).

Thomas Broyer
  • 64,353
  • 7
  • 91
  • 164
  • re your second point, won't that return instances of Post? I'm looking for instances of Comment across all Posts. (Sorry for the late reply, I've been away from a computer) – Rich Apr 18 '11 at 11:10
  • Yes, it will return `Post` instances. I don't think you can get `Comment` instances directly, given that they are `@Embedded` objects. There's no way with MongoDB to do that; eventually _virtual collections_ will make it possible, see http://stackoverflow.com/questions/2138454/filtering-embedded-documents-in-mongodb/2140125#2140125 – Thomas Broyer Apr 19 '11 at 08:23
  • re the second point: Since you are using PlayMorphia module, an easy way to query is `Post post = Post.q().filter("comments.commeter in", users).get()` – Gelin Luo Jan 17 '12 at 05:05