I got a two MongoDB collections like below, (a library only has one book for demonstration purposes):
// books
| _id | author | title |
| ObjectID("yyy") | jean | foo |
| ObjectID("yyy") | paul | bar |
| ObjectID("yyy") | baz | boo |
// library
| _id | name | book |
| ObjectID("xxx") | foobar | ObjectID("yyy") |
| ObjectID("xxx") | pagez | ObjectID("yyy") |
| ObjectID("xxx") | booky | ObjectID("yyy") |
I made a schema for a library like this
export const LibrarySchema = new Schema({
name: {
type: String,
required: true,
},
book: {
_id: false,
type: Schema.Types.ObjectId, // (1)
ref: "Book" // yes, the schema is registered properly, it's called `Book`
}
})
(1) I have the ObjectID since (as shown in the collection) the book is stored with an objectid reference, if I change them to the book schema it won't find them anymore while populating.
Now, the problem comes here, my goal is to have a raw collection which embeds all the libraries and their book, like below:
// library_complete
| _id | name | book |
| ObjId("xxx") | foobar | { author: "jean", title: "foo"} |
| ObjId("xxx") | booky | { author: "baz", title: "boo"} |
(Please don't ask why I need a raw (embedded) collection, I've replicated my goal to be as easily understandable as possible and it's absolutely necessary to have a raw (embedded) collection)
The schema for the raw libary collection is like this:
const RawLibrarySchema = new Schema({
name: {
type: String,
required: true
},
book: {
_id: false,
type: BookSchema, // changing this to `Object` doesn't work either
}
})
Now, in the service when I want to create a book
const linkLibaryToBook = async (library, bookId) => {
// some complex calculations to link library to books and populates it
const libraryBook = await someComplexFunction(library, bookId); // in this function the book gets populated, see the return type below
console.log(libraryBook);
/* @returns
libraryBook {
name: "foobar",
book: { author: "jean", title: "foo" },
}
*/
saveRawLibrary(libraryBook);
}
The above return type is exactly what I want to achieve, now when I write that away like below
const saveRawLibrary = async (libraryObject) => {
console.log(libraryObject);
/* @returns
libraryBook {
name: "foobar",
book: { author: "jean", title: "foo" },
}
// ^ this is as it should be ^
*/
const _library = new libraryModel(libraryObject);
console.log(_library);
/* @returns
_library {
name: "foobar",
book: "9023920dada032aa" // the objectId of the original book
}
// ^ this is what comes out ^
*/
}
all of a sudden mongoose has linked the ID of the book to the library instead of the object. I just want to write the plain object away like shown in the first two console logs. I've also tried using a plain create like this:
const saveRawLibrary = async (libraryObject) => {
await libraryModel.create(libraryObject);
}
However, that does the exact same, it just references it with id... is there a way to just plain insert an object? If you want to see the real object and result you can click here.
TL;DR; I have a JavaScript object which I want to write away, but if I do that, it magically assigns objectIDs instead of the original object.