2015-10-31 6 views
-1

Я хочу построить базу данных (Mongoose/Node.js) Mongodb, но у меня есть проблема прямо сейчас. У меня есть два объекта. Users и Books, и я хочу использовать встроенную систему (из-за отсутствия объединений в mongodb). И моя проблема заключается в том, что из этих объектов shpuld будет внутренним значением для другого.Структура встроенной базы данных Simple Mongodb

Например я WIIL сталкиваюсь с этим два типа запроса в моем приложении:

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 не поддерживает объединения и плохо поддерживает такие вещи. встроенная система - это правильный способ для базы данных NoSql, такой как Mongodb?

+0

В вашем примере вы указали документы, а не внедрены. [Оформить разницу] (http://stackoverflow.com/questions/31487042/confused-about-mongoose-mongo-terminology-are-sub-docs-embedded-docs-also-colle/31487318#31487318). И да, Монго работает лучше всего, когда вы используете встроенные документы, чтобы все книги у пользователя были извлечены только в одном запросе, а не в ссылках, в которые вам нужно будет заполнить (эквивалент объединения). – laggingreflex

+0

@laggingreflex: есть некоторые проблемы в режиме ссылки. я должен выполнить две операции сохранения на один пользовательский ввод, один для сохранения самого документа и один для добавления его идентификатора объекта в качестве ссылки на другой документ. это уместно в монгодбе? это хорошая структура вообще? Другая проблема заключается в запросе, например, мне нужно получить пользователей, которые читают конкретную книгу, я должен запросить сбор пользователей и заполнить книги для каждого из них и проверить, есть ли у каждой из них эта книга или нет, и в конце в результате У меня есть некоторые пользователи с нулевым значением для книг. представьте, что у меня 1 миллион пользователей ... – Fcoder

ответ

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 с ссылочного массива Docs, так как это простой массив _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 } } }) 
+0

, что запрос elemMatch, на который вы написали результаты, «неопределен» для меня. Что там там? Я просто храню идентификатор объекта в книге UserSchema, и я его еще не заполню. – Fcoder

+0

Я использую этот формат: UserSchema.find(). Exec (function (err, result) {}); и я получаю undefined для значения «результат». Я также использую ваш формат, но все еще не определен. я использую Mongoose 4.0.2. но что там там? у нас нет никакого заселения – Fcoder

+0

Я получаю это сообщение в 'err': [Ошибка: не могу использовать $ elemMatch с ObjectId.] – Fcoder

Смежные вопросы