0

I have a mongodb object that looks something like this:

{
    "_id" : "5a567ef6992fb9020474f72d",
    "groupName" : "test, admin, binky, water, brick",
    "users" : [ 
        "test", 
        "admin", 
        "binky", 
        "water", 
        "brick"
    ],
    "comments" : [ 
        {
            "comment" : "test message",
            "createdBy" : "admin",
            "createdAt" : ISODate("2018-01-11T00:01:59.672Z")
        },
        {
            "comment" : "test message",
            "createdBy" : "admin",
            "createdAt" : ISODate("2018-01-11T00:02:48.237Z")
        }
    ],
    "createdBy" : "admin"
}

So, my problem is that I don't want the number of comments to grow infinitely. I want to be able to limit the number of possible comments.

Is there anyway to look at the number of comments when inserting, then maybe delete the first few over 100? So, let's say we get to 101, it would delete the first object???

My code for adding a comment is:

var coll = DatabaseCommon.Instance.GetDatabase("ps_" + siteId).GetCollection<Group>("chatgroups");

var currentGroup = coll.FindOneAndUpdate(y => y._id == groupId, Builders<Group>.Update.Push<Comment>(y => y.comments, comment));

I've tried:

var coll = DatabaseCommon.Instance.GetDatabase("ps_" + siteId).GetCollection<Group>("chatgroups");
coll.UpdateOne({ _id: groupId }, { $push: { comments: { $each: [comment], $slice: -100 } } });

but I always get an error when compiling, saying that it's expecting another close parens.

screenshot of error

2
  • Appending a new comment is trivial compared to removing one at the same time. If you store comments with a reference to the root object however, then you have more options, since you can limit queries to include only the latest N comments, and deletions of older comments can be performed as a background server task, rather than on every insertion. Obviously there are trade-offs. Commented Jan 11, 2018 at 1:31
  • Thanks for the info. Commented Jan 11, 2018 at 2:29

2 Answers 2

1

You can achieve this with $slice

https://docs.mongodb.com/manual/reference/operator/update/slice/

Also, in the case where you don't want to delete any comments, but just want to limit the size an array can be in a single document, you can use a useful technique known as "Bucketing". Here is a question which outlines the technique and syntax in C#

Bucketing with MongoDB C# Driver

Sign up to request clarification or add additional context in comments.

4 Comments

Sorry for the delay, got caught working on something else. I had seen that I can use $slice, but I can't seem to get it to work in my c# code, it always creates an error. Do you have any examples?
Can you update your question with your code and the error you get?
So, I'm finally getting back to this. I attached the error, always wants a close parens, do you see the problem?
I resolved it, but maybe you have a better idea that can do it in one step and make the operation faster???: var coll = DatabaseCommon.Instance.GetDatabase("ps_" + siteId).GetCollection<Group>("chatgroups"); var record = coll.Find(y => y._id == groupId).Single(); record.comments.Add(comment); record.comments = record.comments.Skip(Math.Max(0, record.comments.Count - 100)).ToList(); coll.ReplaceOne(y => y._id == groupId, record);
0

So, I resolved this issue in four steps. First, find the record:

var coll = DatabaseCommon.Instance.GetDatabase("ps_" + siteId).GetCollection<Group>("chatgroups");
var record = coll.Find(y => y._id == groupId).Single();

Then, add the new comment:

record.comments.Add(comment);

Then, only get the last 100 comments:

record.comments = record.comments.Skip(Math.Max(0, record.comments.Count - 100)).ToList();

Save the changed record:

coll.ReplaceOne(y => y._id == groupId, record);

Comments

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.