Store data in ES and not on MongoDB using mongoosastic - mongodb

I am trying to build a search engine project using mongoosastic and was wondering if there was a way to store specific data fields only on elasticsearch and not on MongoDB as this would basically make it duplication of data.
For example we can use the es_indexed to make sure elasticsearch indexes the data and stores it to MongoDB but is there something similar which can make sure elasticsearch indexes the data but MongoDb does not store it.
var mongoose = require('mongoose')
, mongoosastic = require('mongoosastic')
, Schema = mongoose.Schema
var User = new Schema({
name: {type:String, es_indexed:true}
, email: String
, city: String
, comments: {type:[Comment], es_indexed:true}
})
User.plugin(mongoosastic)
I was checking the same with mongoose as well but it wasn't working.
How can i achieve this?

Using select: false will insert the data only to elasticsearch and not mongodb
var mongoose = require('mongoose')
, mongoosastic = require('mongoosastic')
, Schema = mongoose.Schema
var User = new Schema({
name: {type:String, es_indexed:true}
, email: String
, city: String
, comments: {type:[Comment], es_indexed:true, select: false}
})
User.plugin(mongoosastic)

Related

How to use default url for image in mongoose?

var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var url = "https://i.stack.imgur.com/34AD2.jpg";
var UserSChema = new mongoose.Schema({
firstName: String,
lastName: String,
email: String,
profilePic: {type: String, default: url},
username: String,
password: String,
isAdmin: {type: Boolean, default: false}
});
UserSChema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSChema);
The above mentioned is my code i tried that setting string as url and using that but its not working. Whenever i go and check the value in mongo shell the profilePic will be empty.
If there are already documents in your mongo collection it will not update the image URL for them in the database, It will add the default URL when you will save any new data and will also add it old record if you use mongoose to find them.
So while using mongoose you will get the default value https://i.stack.imgur.com/34AD2.jpg always in your code but if see in mongo shell the profilePic for old documents will be empty.
If you want to update the default value of profilePic in all the old documents also, run the below query in Mongo console.
db.getCollection('users').updateMany({},{$set:{"profilePic": "https://i.stack.imgur.com/34AD2.jpg"}})

How to create an Insert trigger in mongodb atlas?

I am new to NoSQL/MongoDB and I need to write a trigger on insert event on one of the collection in my database as follow: Database Name: GiftShop Collection Name: Gifts
Gifts Schema is as Follows:-
const mongoose = require("mongoose");
const userModel = require('./userModel');
const imageModel = require('./imageModel');
const giftSchema = mongoose.Schema({
name: String,
availableQuantity: Number,
price: Number,
Seller: {type: mongoose.Schema.Types.ObjectId,ref: 'UserModel'},
imageName: {type: mongoose.Schema.Types.ObjectId,ref: 'ImageModel'},
deliveryInDays: Number,category: [{type: String, ref: 'CategoryModel'}]
}, {collection: "gifts"});
module.exports = giftSchema;
I have another collection named as a notification. I want to create a trigger as such, as soon as the new gift gets inserted in gift collection the notification collection must get populated with the information having:
gift id,
seller id,
an array of buyer id.
the schema for notification is as follows:
const mongoose = require("mongoose");
const notificationSchema = mongoose.Schema({
seller: { type: mongoose.Schema.Types.ObjectId,ref: 'UserModel'},
buyer: [{type: mongoose.Schema.Types.ObjectId,ref: 'UserModel'}],
newGift: {type: mongoose.Schema.Types.ObjectId,ref: 'GiftModel'}
}, {collection: "notifications"});
module.exports = notificationSchema;
following is the function I wrote in MongoDB atlas but it has many issues with it:
exports = function (changeEvent) {
const {fullDocument} = changeEvent;
const {buyer, seller, newGift} = fullDocument;
const collection = context.services.get("Cluster0").db("test").collection("notification");
return collection.insertOne({buyer, seller, newGift})};
the setup I did on MongoDB atlas to create my trigger:
I am inserting a new gift via MongoDB compass which is connected to my MongoDB atlas but my notification collection is not getting populated with the data mentioned in the schema of notification. Where am I going wrong? and what is the correct way to write the trigger according to my requirement? Thank you.
There are some pointers for debugging stitch functions here, you should be able to follow those to determine if the issue is with your function or the trigger.

mongoose model to connect to mongoDB

i have created model for the mongo collection like below. but it was giving me the collection output which saved in mongoDB.
var mongoose = require('mongoose'),
Schema = mongoose.Schema({
name: {
type: String
},
age: {
type: Number
},
})
module.exports = mongoose.model('container', Schema);}
But later when i changed the last line of the code which is
"module.exports = mongoose.model('container', Schema);"
to
"module.exports = mongoose.model('container', Schema, 'container');"
it worked properly. I check the mongoose document they say to use the previous line, then why didn't it worked.
your problem seems to be from using "Schema" as a variable name
var ContainerSchema = new mongoose.Schema({
...
});
and exporting
module.exports = mongoose.model("Container", ContainerSchema);
would work.

Relations in NoSql using mongoDB and Mongoose

Ok, im comming from an SQL background and I am just getting my hands dirty using MongoDB and Mongoose.
I have two simple models:
CAR:
let mongoose = require('mongoose');
let carsSchema = new mongoose.Schema({
brand: String,
specfifications: [String],
image: String
});
module.exports = mongoose.model('Car', carSchema);
Driver
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let driverSchema = new mongoose.Schema({
name: String,
cars: [{ type: Schema.Types.ObjectId, ref: 'Car' }]
});
module.exports = mongoose.model('Driver', driverSchema);
From what I can understand, this seems to be a proper way of handling a one-to-many-relationship where one car can be used by many drivers.
Now I need to add a class called Races which will be used for saving the results for spacific driver in a specific car.
Thinking in SQL I would do something like this:
let mongoose = require('mongoose');
let raceSchema = new mongoose.Schema({
totaltime: String,
laptime: String,
driver: { type: Schema.Types.ObjectId, ref: 'Driver' },
car: { type: Schema.Types.ObjectId, ref: 'Car' }
});
module.exports = mongoose.model('Race', raceSchema);
Would you consider this to be to correct approach in NoSql or am I forcing my SQL-way of thinking into NoSQL?
the answer is it depends
MongoDB or NoSQL theory says if all related data are in one document, then your query will run faster as they will be stored together. So, in most cases we would prefer one single model for both Car and Driver
If you do not query car and drivers together in most of your queries (chances for which would be rare), then what you did is also correct.
Also, MongoDB has a limitation on size of document i.e. 16 MB if you think the cost of storing them together can go beyond 16MB then what you did is correct. However, there is an alternate solution i.e. GridFS which stores the documents into chunks and overcomes this limitation

Subdocument based on another document

I was wondering if it's possible in Mongoose to have a subdocument based on another document.
Normally I would do something like this:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var CountrySchema = new Schema({
name: String,
info: String,
cities : [
{
type: Schema.ObjectId,
ref: 'Ressource'
}
]
});
module.exports = mongoose.model('Country', CountrySchema);
this however create a new document and then references it via the id to the country document. This is not what I want, I want the resource document to be nested inside the country document. How would I do this?
I found that this fixed my problem:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ressourceSchema = require('../ressource/ressource.model');
var CountrySchema = new Schema({
name: String,
info: String,
cities : [
ressourceSchema.schema
]
});
module.exports = mongoose.model('Country', CountrySchema);