Where is Schema data saved in MongoDB? - mongodb

I am saving some data with Mongoose but unsure where it is saved. Where is this data saved in MongoDb? In which table or collection?
var Chat = mongoose.model('Chat', ChatSchema);
console.log('Message Received: ', msg);
var data = [{
sent: new Date(),
room: 'General',
username: 'Chris',
text: msg
}]
//Loop through each of the chat data and insert into the database
for (var c = 0; c < data.length; c++) {
//Create an instance of the chat model
var entry = new Chat(data[c]);
//Call save to insert the chat
entry.save(function(err, savedChat) {
console.log(savedChat);
});
}

Mongoose by default produces a collection name by passing the model name to the utils.toCollectionName method. This method pluralizes the name.
Check the documentation: http://mongoosejs.com/docs/guide.html (option: collection)
In your case if you connect to the database you will see a collection: chats

Related

How to insert bulk data one db to another db?

I am new to MongoDB. I want to copy some old data from one database to another new database.
I wrote a script that works, but I want to same change in my old data.
Present my data format is:
user {
_id: 1,
username: "jon",
email: "jon#gmail.com"
}
But I want this format:
user {
_id: "621721aed6d2481c999429e5",
username: "jon",
email: "jon#gmail.com",
old_id: 1
}
My script is:
var bulk = db.getSiblingDB("blog-new")["users"].initializeUnorderedBulkOp();
db.getCollection("users").find().forEach(function (d) {
bulk.insert(d);
});
bulk.execute();
How can I solve this issue?
Update
solve this issue using this script-
var bulk = db.getSiblingDB("user-new")["users"].initializeUnorderedBulkOp();
db.getCollection("users").find().forEach(function (d) {
d.old_id = NumberInt(d._id)
d._id = ObjectId()
print("user", d);
bulk.insert(d);
});
bulk.execute();

How to update a nested model in mongoose and mongodb

I'm building a MEAN stack web application.
I have a model in mongoose like this. A model name analyses, where inside , there is a property call points which is another small model name analysis
//model file
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var analysis = new Schema({
ref_id: String,
ele_name: String,
pos_x: Number,
pos_y: Number,
pos_pix_x: Number,
pos_pix_y: Number,
});
var analyses = new Schema({
img_id: String,
store_file_name:String,
points: {
type: [analysis],
default: undefined
},
});
module.exports = mongoose.model('analyses', analyses);
In the database , after I create an entry. there something like this
As you can see, there an id of analyses (5bb...820e) inside have an array of points ( analysis), each has their own id ( 5bb...26d)
Now if I want to update this. I use ExpressJS to define the update API of the server
// API define file
var express = require('express');
var analysesRoutes = express.Router();
// Require Item model in our routes module
var Analyses = require('../models/analyses');
// Defined update route
analysesRoutes.route('/update/:id').put(function (req, res) {
Analyses.findById(req.params.id, function(err, analyses) {
if (!analyses)
return next(new Error('Could not load Document'));
else {
for ( item of Object.keys(req.body)){
analyses[item] = req.body[item];
}
analyses.save().then(analyses => {
res.json({...analyses, status: 200});
})
.catch(err => {
res.status(400).send("unable to update the database");
});
}
});
});
But my problem here is if I want to update only 1 analysis point, I have to send the request to update the big analyses object ( call out id 5bb...820e). Something like this :
//service file
updateAnalyses(newObj, id) {
const uri = 'http://localhost:4000/analyses/update/' + id;
this
.http
.put(uri, newObj)
.subscribe(res => console.log('Done'));
}
// Where newObj here is a big analyses object contains all the unnecessary detail + the point need to be updated
In fact, that point also have an id ( 5bb..26d) itself, is there anyway to update directly to that analysis point ??
Similar question was answered before in Stack overflow.
You can refer to it from here: MongoDB update data in nested field
P.S. There are many answers related to mongodb. Personally the parent.$.child notation worked for me.

Mongodb collection name changed after creation

Problem is that then I run this code, after I check the db records with Robomongo on windows, I see only one collection created with name 'maximas' with two records,
if I remove Model2 from code, after creation result will be the same, but must be collection 'maxima'.
Is there bug in code that i don't see, or this word is reserved, any ideas?
The code,
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/mymodels', (e)=>{
if(e) throw e;
});
var schema = new mongoose.Schema({
text: {type: String}
});
var Model1 = mongoose.model('maxima', schema);
var Model2 = mongoose.model('maximas', schema);
var newData1 = new Model1({
text: 'test'
});
var newData2 = new Model2({
text: 'test'
});
newData1.save((e)=>{
if(e) throw e;
console.log('Saved');
});
newData2.save((e)=>{
if(e) throw e;
console.log('Saved');
});
Mongoose will automatically pluralise your model name as the collection name. This is why they are both the same, as the second collection name is already in plural form.
You can pass the desired collection name as the third model argument:
var Model1 = mongoose.model('maxima', schema, 'maxima');
var Model2 = mongoose.model('maximas', schema, 'maximas');
NOTE: You can also specify your collection name as an option in your schema:
var schema = new mongoose.Schema({
text: { type: String }
}, {
collection: 'maxima'
});
...but in this case you would require a second schema so the first approach above is more suitable here.

Sails js bulk upload and insert into MongoDB

Hi In my Sailsjs application there is bulk upload feature where a admin can upload csv file. I am using csv-parse for parsing the csv content.
Now i want to insert the data into Mongo DB where each row has Vehicle Info and Test Info. These two models have one to many relationship. I am not able to figure out how to insert them into DB. Below is my code for inserting the vehicle.
Below is the code sample i was thinking to create VehicleTest model once Vehicle model is created but i don't have access to vehicle to get info for vechileTest model
Vehicle Model
attributes: {
make: {
type: "string",
required: true
},
tests :{
collection: 'VehicleTest',
via : 'vehicleTested'
},
VechileTest model
attributes: {
vehicleTested :{
modal :'Vehicle',
required:true
},
Below lines of code from the function reads the file and parse it
var parse = require('csv-parse');
var fs = require("fs")
var createdVehicle =[];
var stream = files[0].fd;
fs.readFile(stream, 'utf8', function (err, data) {
// Print the contents of the file as a string here
// and do whatever other string processing you want
parse(data, {columns: true,delimiter:'|'}, function(err, output){
if(output.length>0)
{
for (var i = 0, len = output.length; i < len; i++) {
var vehicle_TestInfo = output[i];
//console.log(vehicle_TestInfo);
//
Vehicle.create({make : vehicle_TestInfo.make,model:vehicle_TestInfo.model,year:vehicle_TestInfo.year ,engineFuel:vehicle_TestInfo.engineFuel,obdZone:vehicle_TestInfo.obdZone,generation:vehicle_TestInfo.generation,protocol:vehicle_TestInfo.protocol,onStar:vehicle_TestInfo.onStar}).exec(function(err,vehCreated){
console.log(vehCreated);
//VehicleTest.Create({vehicleTested:vehCreated._id,overAllComp:vehicle_TestInfo.overAllComp,deviceGeneration:vehicle_TestInfo.deviceGeneration}).exec(function(err,testCreated){
//
// console.log(testCreated);
//
//})
});
}
}
this is how i implemented
for (var i = 0, len = output.length; i < len; i++) {
var vehicle_TestInfo = output[i];
//console.log(vehicle_TestInfo);
//
Vehicle.create({make : vehicle_TestInfo.make,model:vehicle_TestInfo.model,year:vehicle_TestInfo.year ,trim:vehicle_TestInfo.trim ,engineFuel:vehicle_TestInfo.engineFuel,obdZone:vehicle_TestInfo.obdZone,generation:vehicle_TestInfo.generation,protocol:vehicle_TestInfo.protocol,onStar:vehicle_TestInfo.onStar,
tests : {deviceGeneration:vehicle_TestInfo.deviceGeneration,overAllComp:vehicle_TestInfo.overAllComp,isTested:vehicle_TestInfo.isTested,testingInferred:vehicle_TestInfo.testingInferred,vinRead:vehicle_TestInfo.vinRead,
odoRead:vehicle_TestInfo.odoRead,pidRead:vehicle_TestInfo.pidRead,doorLocked:vehicle_TestInfo.doorLocked,SeatBelt:vehicle_TestInfo.seatBelt,fuelLevel:vehicle_TestInfo.fuelLevel,issueType:vehicle_TestInfo.issueType,degreeOfERGIntr:vehicle_TestInfo.degreeOfERGIntr,dataLoggerModel:vehicle_TestInfo.dataLoggerModel,
numberOfVehicle:vehicle_TestInfo.numberOfVehicle,remarks:vehicle_TestInfo.remarks}}).exec(function(err,vehCreated){
if(err && err.originalError && err.originalError.code===50)
{
Vehicle.update({id:vehCreated.id})
}
/// console.log(vehCreated);
// vehCreated.tests.add({})
createdVehicle.push(vehCreated);
});

How to access a preexisting collection with Mongoose?

I have a large collection of 300 question objects in a database test. I can interact with this collection easily through MongoDB's interactive shell; however, when I try to get the collection through Mongoose in an express.js application I get an empty array.
My question is, how can I access this already existing dataset instead of recreating it in express? Here's some code:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
mongoose.model('question', new Schema({ url: String, text: String, id: Number }));
var questions = mongoose.model('question');
questions.find({}, function(err, data) { console.log(err, data, data.length); });
This outputs:
null [] 0
Mongoose added the ability to specify the collection name under the schema, or as the third argument when declaring the model. Otherwise it will use the pluralized version given by the name you map to the model.
Try something like the following, either schema-mapped:
new Schema({ url: String, text: String, id: Number},
{ collection : 'question' }); // collection name
or model mapped:
mongoose.model('Question',
new Schema({ url: String, text: String, id: Number}),
'question'); // collection name
Here's an abstraction of Will Nathan's answer if anyone just wants an easy copy-paste add-in function:
function find (name, query, cb) {
mongoose.connection.db.collection(name, function (err, collection) {
collection.find(query).toArray(cb);
});
}
simply do find(collection_name, query, callback); to be given the result.
for example, if I have a document { a : 1 } in a collection 'foo' and I want to list its properties, I do this:
find('foo', {a : 1}, function (err, docs) {
console.dir(docs);
});
//output: [ { _id: 4e22118fb83406f66a159da5, a: 1 } ]
You can do something like this, than you you'll access the native mongodb functions inside mongoose:
var mongoose = require("mongoose");
mongoose.connect('mongodb://localhost/local');
var connection = mongoose.connection;
connection.on('error', console.error.bind(console, 'connection error:'));
connection.once('open', function () {
connection.db.collection("YourCollectionName", function(err, collection){
collection.find({}).toArray(function(err, data){
console.log(data); // it will print your collection data
})
});
});
Update 2022
If you get an MongoInvalidArgumentError: The callback form of this helper has been removed. error message, here's the new syntax using async/await:
const mongoose = require("mongoose");
mongoose.connect('mongodb://localhost/productsDB');
const connection = mongoose.connection;
connection.on('error', console.error.bind(console, 'connection error:'));
connection.once('open', async function () {
const collection = connection.db.collection("Products");
collection.find({}).toArray(function(err, data){
console.log(data); // it will print your collection data
});
});
I had the same problem and was able to run a schema-less query using an existing Mongoose connection with the code below. I've added a simple constraint 'a=b' to show where you would add such a constraint:
var action = function (err, collection) {
// Locate all the entries using find
collection.find({'a':'b'}).toArray(function(err, results) {
/* whatever you want to do with the results in node such as the following
res.render('home', {
'title': 'MyTitle',
'data': results
});
*/
});
};
mongoose.connection.db.collection('question', action);
Are you sure you've connected to the db? (I ask because I don't see a port specified)
try:
mongoose.connection.on("open", function(){
console.log("mongodb is connected!!");
});
Also, you can do a "show collections" in mongo shell to see the collections within your db - maybe try adding a record via mongoose and see where it ends up?
From the look of your connection string, you should see the record in the "test" db.
Hope it helps!
Something else that was not obvious, to me at least, was that the when using Mongoose's third parameter to avoid replacing the actual collection with a new one with the same name, the new Schema(...) is actually only a placeholder, and doesn't interfere with the exisitng schema so
var User = mongoose.model('User', new Schema({ url: String, text: String, id: Number}, { collection : 'users' })); // collection name;
User.find({}, function(err, data) { console.log(err, data, data.length);});
works fine and returns all fields - even if the actual (remote) Schema contains none of these fields. Mongoose will still want it as new Schema(...), and a variable almost certainly won't hack it.
Go to MongoDB website, Login > Connect > Connect Application > Copy > Paste in 'database_url' > Collections > Copy/Paste in 'collection' .
var mongoose = require("mongoose");
mongoose.connect(' database_url ');
var conn = mongoose.connection;
conn.on('error', console.error.bind(console, 'connection error:'));
conn.once('open', function () {
conn.db.collection(" collection ", function(err, collection){
collection.find({}).toArray(function(err, data){
console.log(data); // data printed in console
})
});
});
I tried all the answers but nothing worked out, finally got the answer hoe to do it.
var mongoose = require('mongoose');
mongoose.connect('mongodb://0.0.0.0:27017/local');
// let model = require('./test1');
setTimeout(async () => {
let coll = mongoose.connection.db.collection(<Your collection name in plural form>);
// let data = await coll.find({}, {limit:2}).toArray();
// let data = await coll.find({name:"Vishal"}, {limit:2}).toArray();
// let data = await coll.find({name:"Vishal"}, {projection:{player:1, _id:0}}).toArray();
let data = await coll.find({}, {limit:3, sort:{name:-1}}).toArray();
console.log(data);
}, 2000);
I have also mentioned some of the criteria to filter out. Delete and update can also be done by this.
Thanks.
Make sure you're connecting to the right database as well as the right collection within the database.
You can include the name of the database in the connection string.
notice databasename in the following connection string:
var mongoose = require('mongoose');
const connectionString = 'mongodb+srv://username:password#hosturl.net/databasename';
mongoose.connect(connectionString);