我想构建一个Mongodb
数据库(Mongoose / Node.js)结构,但我现在面临一个问题。我有两个实体。 Users
和Books
我希望使用嵌入式系统(因为mongodb中缺少连接)。而我的问题是,这些实体中的哪一个对其他实体来说是一种内在价值。
例如,我将在我的应用程序中面对这两种类型的查询:
1- Books of an specific user
2- Users of an specific book
现在,书籍应该是用户的内在价值还是相反的?
我可以做到这两点:
用户架构:
var schema = new mongoose.Schema({
use_name: String,
user_family: String,
user_books: { type: Schema.Types.ObjectId, ref: 'books' }
});
或者这个:
图书架构:
var schema = new mongoose.Schema({
book_name: String,
book_lang: String,
book_user: { type: Schema.Types.ObjectId, ref: 'users' }
});
哪个更好?这是标准方法吗?
如果我同时使用它们,保存时我必须做两次保存操作。如果我有一个包含大量集合的大型数据库,那么这会变得更糟......
经过大量研究后我发现我必须使用嵌入式系统,而不是使用集合之类的关系将实体相互连接,因为Mongodb不支持连接,并且对此类事物的支持很差。嵌入式系统是Mongodb等NoSql数据库的正确方法吗?答案 0 :(得分:0)
首先,有一个小的修正,你的user_books
需要是一个数组[]。
其次,您应该只将一个模式引用到另一个模式中,否则您将不得不增加不必要的复杂性以保持它们的同步。
所以这就是你的模式应该是什么样的:
var UserSchema = new mongoose.Schema({
use_name: String,
user_family: String,
user_books: [{ type: Schema.Types.ObjectId, ref: 'books' }]
});
var BookSchema = new mongoose.Schema({
book_name: String,
book_lang: String,
});
现在“要获取读取特定图书的用户”,您将这样查询:
UserSchema.find({ user_books: book._id })
这将为所有用户提供BOOK_ID
(至少)其中一本图书。
如果就是这样,我想你根本不需要人口。
更新了有关$ elemMatch查询无效的问题:
事实证明,我们实际上并不需要带有引用文档数组的$ elemMatch,因为它是一个简单的_ids数组。
user // =>
{
_id: 56351c611ca0d2e81274100a
name: ...
books: [56351c611ca0d2e81274100b, 56351c611ca0d2e81274100c, ...]
}
$elemMatch
适用于对象数组,并且会出现在嵌入式文档的情况下:
var BookSchema = new mongoose.Schema({
book_name: String,
book_lang: String,
});
var UserSchema = new mongoose.Schema({
use_name: String,
user_family: String,
user_books: [BookSchema]
});
因为在这种情况下,文件将是这样的:
user // =>
{
_id: 56351c611ca0d2e81274100a
name: ...
books: [
{ // each book here has an _id:
_id: 56351c611ca0d2e81274100b,
// this is what `$elemMatch: {_id:` would match for
name: ...
// you could do `$elemMatch: {name:`
lang: ...
// or `$elemMatch: {lang:`
}, {
_id: 56351c611ca0d2e81274100c,
name: ...
lang: ...
}, ...
]
}
这是需要$ elemMatch查询的地方。
UserSchema.find({ user_books: {$elemMatch: {_id: book._id } } })