简体   繁体   English

MongoDB-在单个集合中插入多种类型的对象

[英]MongoDB - insert multiple types of objects in single a collection

I have objects of different classes and would like to store them in a single collection in MongoDB. 我有不同类的对象,并希望将它们存储在MongoDB中的单个集合中。

I'm using asp.net core 2.2 with MongoDB.Driver 2.8.0 and MongoDB 4.0.5. 我正在将ASP.NET Core 2.2与MongoDB.Driver 2.8.0和MongoDB 4.0.5一起使用。 I've done some attempts. 我做了一些尝试。

The idea: I can store all below objects in a single collection. 这个想法:我可以将所有下面的对象存储在一个集合中。 Currently I can save them but I'm not able to read them -> getting "FormatException: Element '_id' does not match any field or property of class Mongo2.Models.MongoEntity." 目前,我可以保存它们,但无法阅读它们->获取"FormatException: Element '_id' does not match any field or property of class Mongo2.Models.MongoEntity." but only after re-running application. 但仅在重新运行应用程序之后。 On empty database I can save object and retrieve them. 在空数据库上,我可以保存对象并检索它们。 When I close the app and don't drop the db then getting exception on collection.Find(book => true).ToList(); } 当我关闭应用程序并且不删除数据库时,在collection.Find(book => true).ToList(); }异常 collection.Find(book => true).ToList(); }

I guess I'm missing some steps or my approach is not valid - couldn't find any workable examples over the internet. 我想我缺少一些步骤,或者我的方法无效-在互联网上找不到任何可行的示例。

Any help will be much appreciated. 任何帮助都感激不尽。 Either by sharing links to working solutions / examples or here. 通过共享指向有效解决方案/示例的链接或在此处。

Model: 模型:

public class MongoEntity
{
}

[BsonIgnoreExtraElements]
public class BookLibrary : MongoEntity
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string BookLibraryId { get; set; }
    public List<Book> Library { get; set; }
}

[BsonIgnoreExtraElements]
public class Book : MongoEntity
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string BookId { get; set; }

    [BsonElement("Name")]
    public string BookName { get; set; }

    [BsonElement("Price")]
    public decimal Price { get; set; }

    [BsonElement("Category")]
    public Category Category { get; set; }

    [BsonElement("Author")]
    public Author Author { get; set; }

    [BsonElement("Date")]
    public DateTime Added { get; set; }
}

[BsonIgnoreExtraElements]
public class Author : MongoEntity
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string AuthorId { get; set; }
    [BsonElement("Author name")]
    public string Name { get; set; }
    [BsonElement("Author last name")]
    public string LastName { get; set; }
}

[BsonIgnoreExtraElements]
public class Category : MongoEntity
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string CategoryId { get; set; }
    [BsonElement("Category name")]
    public string CategoryName { get; set; }
}

Data context: 数据上下文:

public class BookContext
{
    private readonly IMongoDatabase _database;
    private readonly IMongoClient _client;

    public BookContext(IConfiguration configuration)
    {
        _client = new MongoClient(configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>().ConnectionString);
        _database = _client.GetDatabase(configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>().DatabaseName);

    }

    public List<MongoEntity> Get()
    {
        var collection = _database.GetCollection<MongoEntity>("Books");
        return collection.Find(book => true).ToList();
    }

    public void AddBsonDocument()
    {
        var author = new Author()
        {
            Name = "Name",
            LastName = "Lastname",
            AuthorId = ObjectId.GenerateNewId().ToString()
        };

        var category = new Category()
        {
            CategoryId = ObjectId.GenerateNewId().ToString(),
            CategoryName = "Non-fiction"
        };

        var book = new Book()
        {
            BookName = "Random title",
            Category = category,
            Price = 54.93m,
            Added = DateTime.Now,
            BookId = ObjectId.GenerateNewId().ToString(),
            Author = author
        };

        var lib = new BookLibrary(){BookLibraryId = ObjectId.GenerateNewId().ToString(), Library = new List<Book>()};
        lib.Library.Add(book);



        var collection = _database.GetCollection<MongoEntity>("Books");

        var list = new List<MongoEntity> {lib, book, author, category};

        collection.InsertMany(list);

    }
}

The problem is with the Id field. 问题出在Id字段。 You made it custom, but MongoDB will always store your ID property as _id inside the DB and this cannot be changed. 您将其自定义,但是MongoDB始终将ID属性存储为_id并存储在数据库中,并且无法更改。 Trying to alter the name using BsonElementAttribute will be simply ignored. 使用BsonElementAttribute尝试更改名称将被忽略。

To solve your problem you can try the following: 要解决您的问题,您可以尝试以下操作:

  1. Add attribute on CategoryId (and others ids fields too) with BsonElement , but I'm not sure if it works. 使用BsonElementCategoryId (以及其他ids字段)上添加属性,但是我不确定它是否有效。
  2. Change CategoryId to Id (and others ids fields too) CategoryId更改为Id (以及其他ID字段)

The answer turned out to be super easy and obvious but somehow I missed it. 答案非常简单明了,但我却以某种方式错过了答案。

The type of the object is not strongly related to the collection name so I could go with: 对象的类型与集合名称没有密切关系,因此我可以使用:

var books = _database.GetCollection<Books>("Books");
var bookLibraries = _database.GetCollection<BookLibrary>("Books");
var authors = _database.GetCollection<Author>("Books");
var categories = _database.GetCollection<Category>("Books");

Another solution is to use BsonDocument type: 另一个解决方案是使用BsonDocument类型:

var books = _database.GetCollection<BsonDocument>("Books");

Just like that. 就这样

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM