Реализация Mongoose DBRef не такая же, как в документации MongoDB

У меня большая проблема с тривиальной проблемой. Я пытаюсь использовать reference с mongoose.js для базы данных MongoDB. Давайте рассмотрим этот пример:

Пример кода:

https://gist.github.com/hastebrot/1170907

Когда я запускаю этот код, у меня есть что-то подобное в моем db:

> db.stories.find()
{ 
 "title" : "A man who cooked Nintendo",
 "_creator" : ObjectId("52**********************"),
 "_id" : ObjectId("52**********************"),
 "fans" : [ ], "__v" : 0
}

> db.people.find()
{
 "name" : "Aaron",
 "age" : 100,
 "_id" : ObjectId("52**********************"),
 "stories" : [ ], "__v" : 0
}

В чем проблема?

В случае, если я вставляю данные с помощью мангуста и читаю ссылки с использованием мангуста, все в порядке. Но когда db извлекается программой Java с собственным слоем для mongoDB, тогда возникает проблема.

Эта Java-программа добавляет что-то подобное в db (это еще один пример не относится к полям, не совпадающим):

//other fields
"user": {
 "$ref": "users",
 "$id": {
 "$oid": "52c6c497c08e6fcf37000001"
 }
}

Когда мы переходим к документации MongoDB (http://docs.mongodb.org/manual/reference/database-references/#dbrefs), мы можем прочитать, что для ссылочного свойства нужны поля $ref и $id.

Вопрос:

Так что это проблема с неправильной реализацией mongoDB DBRef типа в мангусте или я что-то не так?

1 ответ

Ссылка в мангусте - это ручная ссылка, а не dbref (использование которой я расскажу позже). На высоком уровне здесь происходит то, что он встраивает ObjectId человека как значение в поле _creator. Затем, если вы хотите "использовать" эти отношения, скажем, ища все истории, созданные человеком под названием "Аарон", будет эффективно два запроса:

  • Первый запрос будет получать _id имен человека Аароном из коллекции людей, то есть: db.people.findOne({"name": "Aaron"})
  • Второй запрос будет использовать этот _id для поиска всех историй с этим создателем, то есть: db.stories.find({"creator": ObjectId("52**********************")})

ORM (mongoose в этом случае) абстрагирует это для вас и позволяет вам определять отношения и т.д., Не зная, что происходит под обложками.

Когда вы пытаетесь сделать это с помощью родного драйвера вне ORM, вы сделали фундаментальную ошибку с точки зрения того, как она действительно достигает этих отношений. Он не использует ссылки на базы данных, и в целом их использование не рекомендуется (см. Первую заметку о справочных ссылках в документах), скорее использует нечто похожее на то, что я описал выше.

Если вы хотите эмулировать функциональность, вы должны сделать что-то подобное и избегать использования ссылок на базы данных.

licensed under cc by-sa 3.0 with attribution.