1

I have an order collection that looks like :

{
        "_id" : ObjectId("5d732c3eb52e554e5ce19d96"),
        "UpdatedDate" : ISODate("2019-09-07T04:04:14.223Z"),
        "customerId" : ObjectId("5d579deac9406a6db80960b7"),
        "items" : [ 
            {
                "product" : ObjectId("5d231c3fb52e554e5ce12d14"),
                "quantity" : 2
            }, 
            {
                "product" : ObjectId("5836bc0b291918eb42966320"),
                "quantity" : 1
            }
        ]
}

while product collection :

[ 
    {
        "_id" : ObjectId("5d231c3fb52e554e5ce12d14"),
        "name" : "Coffee"
    }, 
    {
        "_id" : ObjectId("5836bc0b291918eb42966320"),
        "name" : "Cake"
    }
]

How should I do the join through MongoDB .Net driver in order to get the product name and customer name projected into the result ?

Thank you

1
  • use aggregate lookup or mongoose populate on "items.product" Commented Sep 7, 2019 at 8:31

1 Answer 1

1

here's a full example of how to join 2 collections using the IMongoQueryable interface of the driver. below code uses MongoDB.Entities for brevity but joining part is exactly the same for the official driver. simply replace DB.Queryable<Order>() with collection.AsQueryable()

using MongoDB.Entities;
using MongoDB.Driver.Linq;
using System;
using System.Linq;

namespace StackOverflow
{
    public class Program
    {
        public class Customer : Entity
        {
            public string Name { get; set; }
            public Many<Order> Orders { get; set; }

            public Customer() => this.InitOneToMany(() => Orders);
        }

        public class Order : Entity
        {
            public One<Customer> Customer { get; set; }
            public OrderItem[] Items { get; set; }
        }

        public class Product : Entity
        {
            public string Name { get; set; }
            public decimal Price { get; set; }
        }

        public class OrderItem //embedded entity inside order
        {
            public One<Product> Product { get; set; }
            public int Quantity { get; set; }
        }

        private static void Main(string[] args)
        {
            //initialize db connection
            new DB("cafe-db", "localhost", 27017);

            //create some products
            var cake = new Product { Name = "Cake", Price = 9.99m };
            var coffee = new Product { Name = "Coffee", Price = 6.66m };
            cake.Save();
            coffee.Save();

            //create a customer
            var customer = new Customer { Name = "Mike Posner" };
            customer.Save();

            //create an order
            var order = new Order
            {
                Customer = customer.ToReference(),
                Items = (new[]
                {
                    new OrderItem {
                        Product = cake.ToReference(),
                        Quantity = 2
                    },

                    new OrderItem {
                        Product = coffee.ToReference(),
                        Quantity = 1
                    }
                })
            };
            order.Save();

            //link the order to the customer
            customer.Orders.Add(order);

            // retrieve the data needed to generate an order summary/ invoice given just an order id
            var orderID = order.ID;

            var result = DB.Queryable<Order>()
                           .Where(o => o.ID == orderID)
                           .SelectMany(o => o.Items,
                                            (o, i) => new { productID = i.Product.ID, productQTY = i.Quantity })
                           .Join(
                                DB.Queryable<Product>(),  //foregign collection
                                x => x.productID,         //local field
                                p => p.ID,                //foreign field
                                (x, p) => new             //projection
                                {
                                    productName = p.Name,
                                    productPrice = p.Price,
                                    productQty = x.productQTY
                                })
                           .ToList();

            var customerName = DB.Find<Order>()
                                 .One(orderID)
                                 .Customer.ToEntity()
                                 .Name;

            Console.WriteLine($"CUSTOMER: {customerName}");

            foreach (var x in result)
            {
                Console.WriteLine($"PRODCUT: {x.productName} | QTY: {x.productQty} | PRICE: {x.productPrice}");
            }

            Console.Read();
        }
    }
}
Sign up to request clarification or add additional context in comments.

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.