Waxren
Waxren

Reputation: 2172

How to join two collections using lookup operator in C# Mongodb strongly typed driver

I am using the official C# MongoDb strongly typed driver version 2.8.0 to interact with MongoDB.

Consider the following classes:

public class Author {
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string BirthDate { get; set; }

    public string ScientificDegree { get; set; }
}

public class Book
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    public string AuthorId {get; set;}

    public string Title { get; set; }

    public int PublishYear { get; set; }

    public string Content { get; set; }

    public bool IsVerified { get; set; }

    public int DownloadCount {get; set; }
}

How to join (one to one) the two collections by the Id field in the author document and the AuthorId field in the Book document without using Linq and by using the lookup operator and the aggregation framwork.

Upvotes: 1

Views: 11071

Answers (2)

Dĵ ΝιΓΞΗΛψΚ
Dĵ ΝιΓΞΗΛψΚ

Reputation: 5669

you can do one-to-one, one-to-many, many-to-many relationships quite easily with the MongoDB.Entities wrapper library. the following is how you do one-to-one relationships with two different collections.

using System.Linq;
using MongoDB.Entities;

namespace Library
{
    public class Author : Entity
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

    public class Book : Entity
    {
        public string Title { get; set; }
        public One<Author> MainAuthor { get; set; } // one-to-one relationship
    }

    class Program
    {
        static void Main(string[] args)
        {
            new DB("library");

            var author1 = new Author
            {
                FirstName = "Eckhart",
                LastName = "Tolle"
            };
            author1.Save();

            var book1 = new Book
            {
                Title = "The Power Of Now",
                MainAuthor = author1.ToReference()
            };
            book1.Save();

            var powerOfNow = DB.Collection<Book>()
                               .Where(b => b.Title.Contains("Now"))
                               .FirstOrDefault();

            var eckhartTolle = powerOfNow.MainAuthor.ToEntity();
        }
    }
}

Upvotes: 0

user11380812
user11380812

Reputation:

If you use the peek definition of Visual Studio, it will show what Lookup to expect, as shown in the image below, surrounded with red.

enter image description here

The first Lookup is an extension of the IMongoCollection. It executes in the context of the collection and requires a foreign key collection as the first parameter, then the local field on which relation is established, the foreign field that composes the relation, and finally the result type. Unfortunately, the result type cannot be an anonymous type (or I did not discover how to be anonymous?). As always is expected that from the foreign collection will be returned more than one element, so, the operator always expects an array to be returned.

In your case, the result will be as shown in the snippet below. You should create 'LookedUpBooks' class as well.

 var result = await collBooks.Aggregate()
                .Lookup<Books, Authors, LookedUpBooks>(collAuthors, 
                    x => x.AuthorId, 
                    y => y.Id,
                    y => y.LastName
            ).ToListAsync();

public class LookedUpBooks
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
     public string Id { get; set; }

     public string Title { get; set; }
// Add more properties as you need

     public IEnumerable<Authors> InnerAuthors { get; set; }
}

See more on How to Program with MongoDB Using the .NET Driver

Upvotes: 4

Related Questions