Mongo DB C# driver, handling a single objekt

206 views
Skip to first unread message

Mattias

unread,
Mar 22, 2016, 11:05:25 AM3/22/16
to mongodb-user
Hello!

I'm new to Mongo DB and have been trying to use the mongo DB C# driver to make a database with POCO-classes.

My classes look like this:

 public class Blog
   
{


       
public Blog()
       
{
           
Posts = new List<Posts>();
       
}
       
public ObjectId _id { get; set; }
       
public List<Post> Posts { get; set; }
   
}
   
public class Post
   
{
       
public ObjectId postid { get; set; }
   
}


Other classes will inherit from "Posts" so that they can hold different content.

The problem is that I can't find a way to return a single post. The suggested solution that I have tried is this:


 
public void asd(ObjectId blogId, ObjectId postId)
       
{
           
List<Post> commandList = new List<Post>();
           
MongoClient _client = new MongoClient();
           
IMongoDatabase database = client.GetDatabase("BlogDB");
           
IMongoCollection<Blog> collection = _database.GetCollection<Blog>("Blogs");
           
var filter = Builders<Blog>.Filter.Eq("_id", blogId);
           
var blogs = collection.Find(filter).FirstOrDefault();
           
foreach(Post post in blogs.Posts)
           
{
               
if (post.postid == postId)
               
{
                   
// do something with post ... post.myFunction();  or post.propertyN or return post
                   
Console.WriteLine("This is a type of post + " + post.GetType().ToString());
               
}
           
}
       
}



This solution retrieves all posts and places them in a foreach() - loop which doesn't seem like the right way to do it. If I have posts containing large files (such as video) wouldn't this be very slow?

I want to be able to return a single post as an object Post.


Wan Bachtiar

unread,
Mar 30, 2016, 3:12:31 AM3/30/16
to mongodb-user

The problem is that I can’t find a way to return a single post.

Hi Mattias,

You could use Projections to project only the matching element entry of posts. In this case posts field is an array, and you could use the positional $ operator to return the first element match.

For example:

var filterBuilder = Builders<Blog>.Filter;
var filter = filterBuilder.Eq("_id", blogId) & filterBuilder.Eq("posts.postid", postId));

var projection = Builders<Blog>.Projection.Include("posts.$");
Blog blog = collectionBlog.Find<Blog>(filter).Project<Blog>(projection).FirstOrDefault<Blog>();

// There should be one post in blog.posts array
Console.WriteLine(blog.posts.First());

The above snippet was tested in .Net v4.5.2 and mongocsharpdriver-2.2.3.

Having said the above, you may need to consider your schema design. Assuming it is normal blog posts, the size of a post can be quite large and when you have many post entries it can be too large for a single BSON document. See Document Growth.

As an example design, you could consider having two separate collections, post and blog. Where a post document has a reference to a blog id.
I would recommend to check out the Data Modelling Introduction, it has good examples and information on references data structure and embedded data structure. You can test different data models for your use case and analyse each strengths and weaknesses.

If I have posts containing large files (such as video) wouldn’t this be very slow?

Generally instead of embedding the video file in the document, only the URL of the video is stored.
However should the need arise to store binary data in a document you may want to look into GridFS. Also see Building MongoDB Application binary files using GridFS.

Regards,

Wan.

Reply all
Reply to author
Forward
0 new messages