differentiating Objects with same value in a collection in mongodb - mongodb

I have a model named author:
export const authorInfoSchema = new Schema({
a_id: String,
firstName: String,
lastName: String,
birthDay: String,
});
for each author I want to add objects as a Schema named books:
const bookSchema = new Schema({
book_id: String,
bookName: String,
bookDis: String,
bookDate: Date,
bookAuthor: String,
pageNo: Number,
});
but there could be a case where 2 or more authors have the same name, how can I differentiate between the authors and link them to their right books?

Related

MongoDB - will the collection referencing another collection be also updated when referenced collection updates and vice versa?

If I update a field in collection B that is referenced by collection A, will collection A update too? Also vice versa?
collection A:
const userSchema = new mongoose.Schema({
email: String,
userName: String, //lets say I update username
password: String,
favoriteBooks: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Book'
}
})
collection B:
const bookSchema = new mongoose.Schema({
name: String,
reviews: [String] //lets say I update or add review
})
If I update a subdocument:
collection A:
const userSchema = new mongoose.Schema({
email: String,
userName: String, //lets say I update username
password: String,
favoriteBooks: [BookSchema]
})
collection B:
const bookSchema = new mongoose.Schema({
name: String,
likesCount: Number
})
Thanks

How to find a document based on the embedded object key value?

Using mongoose .findOne() how would you find a document based on the key value that is deep into the object? Like for example how would I find a document based on the meta.votes value?
var blogSchema = new Schema({
title: String, // String is shorthand for {type: String}
author: String,
body: String,
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
hidden: Boolean,
meta: {
votes: Number,
favs: Number
}
});

Mongodb Schema using mongoose

This is my user schema :
const userSchema = new Schema({
email: String,
username: String,
password: String,
secretToken: String,
active: Boolean,
type: String
}, {
timestamps: { // this will give us the detail when the account is created
createdAt: 'createdAt',
updatedAt: 'updatedAt'
}
});
this is my requirement Schema:
const requirementSchema = new Schema({
name: String,
age: String,
class: String,
subject: String,
email: String
}, {
timestamps: { // this will give us the detail when the requiremnt is created
createdAt: 'createdAt',
updatedAt: 'updatedAt'
}
});
how can I bring id from user schema to the requirement schema as secondary key?
I think mongodb is not meant for relationship. I could led to very bad practice if your database grow. But you can try https://docs.mongodb.com/manual/reference/database-references/#DatabaseReferences-DBRef for Database References.
There is no primary key foreign key concept in Mongodb. and normalization is also discouraged in mongodb.

MongoDB using mongoose for populate

I am having collection1 with one of the column as ref of collection2. Now i want to populate(join) collection1 and collection2 with some condition on collection2 fields. Is it possible?
What i want to do is
models.Encounter
.where('practice').equals(practice)
.populate({
path:'chart',
match:{firstName:{ $regex: new RegExp(Name.toLowerCase(), 'i') }},
select:'firstName lastName'})
.populate('provider', 'firstName lastName')
.populate('signedBy', 'firstName lastName')
.sort('-date')
.limit(100)
.exec(function (err, encounters) {})
Here charts is collection and for me match is not working..Where Name comes from jade engine. null values are coming for firstname
Practice Schema:
The schemas are
var practiceSchema = mongoose.Schema({
name: String,
internalName: String,
address: addressSchema,
phone: String,
taxId: String
});
Chart Schema:
var chartSchema = mongoose.Schema({
created: Date,
updated: Date,
practice: {type: mongoose.Schema.ObjectId, ref : 'practices', required: true},
mrn: String,
firstName: String,
lastName: String,
emailWork: String,
phoneHome: String,
phoneMobile: String,
dob: Date,
married: Boolean,
smoker: Boolean
});
Now i want to get data from Encounters by populating charts and also charts.firstName == 'XYZ' and charts.lastName == 'ABC'.. I have done this by getting all data from encounters and then applying filter on charts. But it is taking too much of time..

Reference field within same schema

Is it possible to reference field within same schema? See my example below. Or am I going about this wrong way?
var UserSchema = new mongoose.Schema ({
username: String,
password: String,
email: String,
foods: [{
name: String,
category: String,
ingredients: // how to reference values in the ingredients array?
}],
ingredients: [{
name: String,
category: String
}]
});
Short answer
This is a core MongoDB design decision: MongoDB relationships: embed or reference?
Storing references to objects, rather than independent copies of them, as you would do in a relational database is possible in MongoDB and often done, it just results in more and more complex queries when you need to look them up.
Long answer
If the goal is just to keep the definitions of ingredient schemas consistent, you can define a schema and use it twice. The ingredients will be stored as independent copies, e.g.
[{ username: 'bob',
ingredients: [ { name: 'Carrot', category: 'Vegetable' } , ...],
foods: [ { name: 'Salad', category: 'Lunch', ingredients: [ { name: 'Carrot', category: 'Vegetable'}, ...]}]
}, ...]
var IngredientSchema = new mongoose.Schema({
name: String,
category: String,
});
var UserSchema = new mongoose.Schema ({
username: String,
password: String,
email: String,
foods: [{
name: String,
category: String,
ingredients: [IngredientSchema] // brackets indicates it's an array,
}],
ingredients: [IngredientSchema]
});
Alternatively you can reference ingredients by objectId:
var UserSchema = new mongoose.Schema ({
username: String,
password: String,
email: String,
foods: [{
name: String,
category: String,
ingredients: [mongoose.Schema.Types.ObjectId] // IDs reference individual ingredients,
}],
ingredients: [IngredientSchema]
});
By defining IngredientSchema explicitly, each ingredient object gets its own ObjectId when it is declared. The upside to storing IDs of ingredients (rather than copies of ingredient objects) is more concise and consistent storage. The downside is there will be many more and more complex queries.
[{ username: 'bob',
ingredients: [ { _id: ObjectId('a298d9ef898afc98ddf'), name: 'Carrot', category: 'Vegetable' } , ...],
foods: [ { name: 'Salad', category: 'Lunch', ingredients: [ {$oid: 'a298d9ef898afc98ddf'}, ]}]
}, ...]
A better approach if you want to store references to Ingredients, may be to store Ingredients as its own first class collection. You'll still have many separate queries when you want to look up foods by ingredient, or ingredients by food, but the queries will be simpler.
var UserSchema = new mongoose.Schema ({
username: String,
password: String,
email: String,
foods: [{
name: String,
category: String,
ingredients: [mongoose.Schema.Types.ObjectId] // IDs reference individual ingredients,
}],
ingredients: [mongoose.Schema.Types.ObjectId]
});
if the goal is store normalized references to ingredients and search foods based on them, to quote another [SO post][1], "this is one of those cases where relational databases really shine"
See this SO post for querying subdocuments by Id:
Reading categories and number of articles in a single query
As one respondent notes, "this is one of those cases where relational databases really shine"