【问题标题】:Relationships in MongoDB (using .Net)MongoDB 中的关系(使用 .Net)
【发布时间】:2019-10-18 06:05:10
【问题描述】:

在 mongoDB 中是否有使用 .Net 创建某种等同于“SQL-Join”的东西? 我已经阅读了有关关系的 MongoDB 文档 (https://docs.mongodb.com/manual/tutorial/model-referenced-one-to-many-relationships-between-documents/)。据我了解,您只需通过引用它们的 ID 来添加关系。然而..这是否也意味着对于每一个关系你还需要做一个额外的查询?..

【问题讨论】:

  • 看看MongoDB.Entities 包装库。它内置了对one-to-oneone-to-manymany-to-many 关系的支持

标签: c# .net mongodb mongodb-query mongodb-.net-driver


【解决方案1】:

考虑如下最简单的关系:

db.publishers.save({
    _id: "oreilly",
    name: "O'Reilly Media",
    founded: 1980,
    location: "CA"
})

db.books.save({
    _id: 123456789,
    title: "MongoDB: The Definitive Guide",
    author: [ "Kristina Chodorow", "Mike Dirolf" ],
    published_date: ISODate("2010-09-24"),
    pages: 216,
    language: "English",
    publisher_id: "oreilly"
})

在 MongoDB 中,您可以使用 $lookup 运算符在一个查询中从两个集合中获取数据:

db.books.aggregate([
    {
        $lookup: {
            from: "publishers",
            localField: "publisher_id",
            foreignField: "_id",
            as: "publisher"
        }
    }
])

返回:

{ 
    "_id" : 123456789, 
    "title" : "MongoDB: The Definitive Guide", 
    "author" : [ "Kristina Chodorow", "Mike Dirolf" ], 
    "published_date" : ISODate("2010-09-24T00:00:00Z"), 
    "pages" : 216, 
    "language" : "English", 
    "publisher_id" : "oreilly", 
    "publisher" : [ { "_id" : "oreilly", "name" : "O'Reilly Media", "founded" : 1980, "location" : "CA" } ] 
}

使用 MongoDB .NET 驱动程序,您可以使用 LINQ 语法和 join 运算符,这些运算符将被转换为 $lookup

var books = db.GetCollection<Book>("books");
var publishers = db.GetCollection<Publisher>("publishers");

var q = from book in books.AsQueryable()
        join publisher in publishers.AsQueryable() on
            book.publisher_id equals publisher._id
        select new
        {
            book,
            publisher = publisher
        };

var result = q.ToList();

$unwind 翻译成$lookup,这样你就得到一个publisher 对象而不是数组

【讨论】:

    【解决方案2】:

    如果您不介意使用库,MongoDB.Entities 可以很容易地建立关系,而无需手动进行连接,除非您真的想这样做:-)

    看看下面的代码,它演示了作者和书籍实体之间的一对多关系。图书实体对作者一无所知。但是您仍然可以通过提供书籍 ID、书籍 ID 数组甚至书籍的 IQueryable 来获得反向关系访问。 [免责声明:我是图书馆的作者]

    using System;
    using System.Linq;
    using MongoDB.Entities;
    using MongoDB.Driver.Linq;
    
    namespace StackOverflow
    {
        public class Program
        {
            public class Author : Entity
            {
                public string Name { get; set; }
                public Many<Book> Books { get; set; }
    
                public Author() => this.InitOneToMany(() => Books);
            }
    
            public class Book : Entity
            {
                public string Title { get; set; }
            }
    
            static void Main(string[] args)
            {
                new DB("test");
    
                var book = new Book { Title = "The Power Of Now" };
                book.Save();
    
                var author = new Author { Name = "Eckhart Tolle" };
                author.Save();
    
                author.Books.Add(book);
    
                //build a query for finding all books that has Power in the title.
                var bookQuery = DB.Queryable<Book>()
                                  .Where(b => b.Title.Contains("Power"));
    
                //find all the authors of books that has a title with Power in them
                var authors = author.Books
                                    .ParentsQueryable<Author>(bookQuery);
    
                //get the result
                var result = authors.ToArray();
    
                //output the aggregation pipeline
                Console.WriteLine(authors.ToString());
    
    
                Console.ReadKey();
            }
        }
    }
    

    【讨论】:

    • 这个库似乎很不受欢迎(目前),这使得它在生产代码中使用起来没有吸引力。我的意思是,6 次分叉 30 颗星和 5631 次 nuget 下载并不表示产品成熟。不过,为您的成功祈祷!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    • 2020-10-08
    • 1970-01-01
    • 2016-04-23
    • 2011-08-04
    • 2017-04-05
    • 1970-01-01
    相关资源
    最近更新 更多