MongoDB.Driver multiple Unwind and Group

62 Views Asked by At

I am trying to filter multiple field for retrieving not deleted Document and its not deleted collection items. Here is my example code.

var filter = Builders<Document>.Filter.Eq(rp => rp.IsDeleted, false)
var cursor = await documentRepository._collection.Aggregate()
    .Match(filter)
    .Unwind(rp => rp.Users)
    .Unwind("Users.Friends")
    .Match(Builders<BsonDocument>.Filter.Eq("Users.IsDeleted", false))
    .Match(Builders<BsonDocument>.Filter.Eq("Users.Friends.IsDeleted", false))
    .Lookup(
        foreignCollectionName: "Users",
        localField: "Users.Friends",
        foreignField: "_id",
        @as: "Users.Friends"
    )
    .Group(
        new BsonDocument
        {
            { "_id", "$_id" },
            { "Language", new BsonDocument("$first", "$Language") },
            { "Title", new BsonDocument("$first", "$Title") },
            { "Content", new BsonDocument("$first", "$Content") },
            { "IsDeleted", new BsonDocument("$first", "$IsDeleted") },
            { "CreateDate", new BsonDocument("$first", "$CreateDate") },
            { "ModifiedDate", new BsonDocument("$first", "$ModifiedDate") },
            { "Users", new BsonDocument("$push", "$Users") },
        })
    .ToListAsync()
var test = cursor.Select(v => BsonSerializer.Deserialize<Document>(v)).ToList();

My class structure is

public class Document : MongoEntity
{
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; init; }

    public Language Language { get; init; }
    public required string Title { get; set; }

    public required string Content { get; set; }

    [BsonElement("Users")]
    public List<User> Users { get; set; }
}

public class User : MongoEntity
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    [BsonElement("Friends")]
    public List<Friend> Friends { get; set; }
}

public class Friend : MongoEntity
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

My problem is that Friends is not added inside Users. I am trying a lot of way but I couldn't make it.

How can I do that?

Note: Additionally, I might have List inside friends, and I also want to add filter and unwinding it. In this case is this the best way, or are there better ways for this situation?

var filter = Builders<Document>.Filter.Eq(rp => rp.IsDeleted, false);

var cursor = await documentRepository._collection.Aggregate()
    .Match(filter)
    .Unwind(rp => rp.Users)
    .Unwind("Users.Friends")
    .Match(Builders<BsonDocument>.Filter.Eq("Users.IsDeleted", false))
    .Match(Builders<BsonDocument>.Filter.Eq("Users.Friends.IsDeleted", false))
    .Lookup(
        foreignCollectionName: "Users",
        localField: "Users.Friends",
        foreignField: "_id",
        @as: "Users.Friends"
    )
    .Group(
        new BsonDocument
        {
            { "_id", "$_id" },
            { "Language", new BsonDocument("$first", "$Language") },
            { "Title", new BsonDocument("$first", "$Title") },
            { "Content", new BsonDocument("$first", "$Content") },
            { "IsDeleted", new BsonDocument("$first", "$IsDeleted") },
            { "CreateDate", new BsonDocument("$first", "$CreateDate") },
            { "ModifiedDate", new BsonDocument("$first", "$ModifiedDate") },
            { "Users", new BsonDocument("$push", "$Users") },
        })
    .ToListAsync()
var test = cursor.Select(v => BsonSerializer.Deserialize<Document>(v)).ToList();
0

There are 0 best solutions below