I am still trying to comprehend Mongoose/Mongo
Now in terminal When I do something like this in terminal
use library
show collections
db.authors.find().pretty()
I get something like this in logged
{
"_id" : ObjectId("5bc8704f3a9828d5513505a2"),
"name" : "Aman",
"age" : "21",
"__v" : 0
}
{
"_id" : ObjectId("5bc870553a9828d5513505a3"),
"name" : "Rohit",
"age" : "20",
"__v" : 0
}
{
"_id" : ObjectId("5bc8704f3a9828d5513505a7"),
"name" : "Aman",
"age" : "21",
"__v" : 0
}
{
"_id" : ObjectId("5bc870553a9828d5513505a5"),
"name" : "Rohit",
"age" : "20",
"__v" : 0
}
Now, I want to have same data in my NodeJs i.e say, I want to find wherever the name is Rohit and want to link it with with some other db or schema.
how can I get the same output which I just obtained by running the above given command in terminal window of mongo in NodeJS
Obviously doing something like this console.log(db.authors.find()) won't work, so how can I get that?
This is how I usually write my database queries.
First create a schema that your model will follow. Don't worry this schema is flexible and you can change it at any time without affecting old data.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var authorSchema = new Schema({
name: {
type: String,
required: true
},
age: {
type: Number,
default: 20
}
});
Next create a model from your schema.
var authorModel = mongoose.model('authorModel', authorSchema);
Lastly query your model and get the value you need
authorModel.find(
{
name: 'Rohit'
},
function (err, result) {
console.log(result)
});
I put my schema and controller on separate files. How you organise your code structure is up to you.
I pretty much followed this blog when I first learnt to build APIs on NodeJS. You might find this useful as well!
Related
I am using Azure cosmos db with the Mongodb API. Also i am using mongoose to create schemas and create new documents in the database. I am also using Node.js.
At this point I am considering using a One-to-Many relationship with embedded documents.
The data structure is like this :
{
"_id" : "locality1",
"_type" : "Locality",
"name" : "Wallmart",
"subsectionList" : [
{
"_id" : "subsection1",
"_type" : "SubSection",
"name" : "First floor",
"sensorList" : [
{
"_id" : "sensor1",
"_type" : "Sensor",
"placement" : "In the hallway"
},
{
"_id" : "sensor2",
"_type" : "Sensor",
"placement" : "In the ceiling"
}
]
},
{
"_id" : "subsection2",
"_type" : "SubSection",
"name" : "Second floor",
"sensorList" : [ ],
}
],
}
I want to retrieve ONLY the "sensor1"-object, not anything from the parent.
Using querying i am only able to retrieve the entire "locality1"-object, with all its underlying subsections and sensors. On a larger scale that is an unnecessary large amount of data.
Here is my query so far.
Locality.find().where('subsectionList.sensorList._id').equals("sensor1").then(doc => {
console.log(doc)
})
I appreciate any tips! :)
Based on my test, i can't get rid of the _id property anyway even though i followed the parameters which is mentioned here.
Locality.find({},'subsectionList', function (err, locas)
The above query still return the results including _id property.(It seems a default item)
I get a workaround from this blog that you could loop the array to filter your desired columns.
var mongoose = require('mongoose');
var COSMOSDB_CONNSTR= "mongodb://***.documents.azure.com:10255/db";
var COSMODDB_USER= "***";
var COSMOSDB_PASSWORD= "***";
mongoose.connect(COSMOSDB_CONNSTR+"?ssl=true&replicaSet=globaldb", {
auth: {
user: COSMODDB_USER,
password: COSMOSDB_PASSWORD
}
}).then(() => console.log('Connection to CosmosDB successful'))
.catch((err) => console.error(err));
const Locality = mongoose.model('Locality', new mongoose.Schema({
_id: String,
subsectionList: [{
sensorList: [{
_id: String,
_type: String,
placement: String
}]
}]
}));
Locality.find({},'subsectionList', function (err, locas) {
if (err) return handleError(err);
var returnArray = [];
for(var i = 0; i<locas.length;i++){
for(var j = 0; j<locas[i].subsectionList.length;j++){
for(var k = 0; k<locas[i].subsectionList[j].sensorList.length;k++){
if(locas[i].subsectionList[j].sensorList[k]._id == 'sensor1')
returnArray.push(locas[i].subsectionList[j].sensorList[k]);
}
}
}
console.log(returnArray);
});
This is an abstract example, but if someone can help me to solve it, I will be eternally grateful.
I am trying to do a search based on a field in a related record. In this example we have a hierarchy of subjects, that are nested using the parent_subject field. This is the Mongoose definition I have used:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var subjectSchema = new Schema({
url: { type: String, required: true, unique: true },
title: { type: String, required: true, unique: true },
parent_subject: this
});
module.exports = mongoose.model('Subject', subjectSchema);
Some records in my MongoDB:
{
"_id" : ObjectId("5a3857f1afeb498c9533aef1"),
"title" : "Sport",
"url" : "sport",
"__v" : 0
},
{
"_id" : ObjectId("5a3d9a409c0973976f7889c6"),
"title" : "Cycling",
"__v" : 0,
"parent_subject" : ObjectId("5a3857f1afeb498c9533aef1"),
"url" : "cycling"
},
{
"_id" : ObjectId("5a3d9a7e9c0973976f788b48"),
"title" : "Mountain Biking",
"__v" : 0,
"parent_subject" : ObjectId("5a3d9a409c0973976f7889c6"),
"url" : "mountain biking"
}
I would like to know how I can query this data based on a field in the parent record. For example, I would like to find all the subjects that have a parent subject with the title "Sport". In SQL, I would do the following query:
SELECT *
FROM subject
INNER JOIN subject AS parentSubject
ON subject.parent_subject = parentSubject.id
WHERE parentSubject.title = "Sport";
How would I achieve this with a MongoDB?
You can use mongodb aggregate pipeline and lookup for this
`Subject.aggregate([
{
$lookup:
{
from: "parentSubject",
localField: "parent_subject",
foreignField: "id"
as: "parentSubject"
}
},
{$unwind:"$parentSubject"},
{$match:{"$parentSubject.title":"Sport"}}
])`
For more reference you can see https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/index.html
The point of mongoDB is that it is NOSQl, so that you also cannot use joins.
Your best option would be to first acquire the parentSubject and it's id.
And afterwards go for the subjects related to that id.
Since your data already has a subject.parent_subject it should be pretty easy to do.
I have a schema in Mongoose that looks like this:
const SocketDetailsUserSchema = new mongoose.Schema({
userId: String,
socketValue: [{
id: String,
data : String
}],
isDeleted: Boolean,
dateCreated: Date,
updateAt: Date
});
I want to insert data of socketValue in key value pair in array format. Which should look like ,
{
"_id" : ObjectId("5a12809c7f7afb1e3626857f"),
"userId" : "59eee19696fe6560cd54a081",
"socketValue" : [{"id":"5a05855b10600e4aa5b3a48e" , "value" : "123" }],[{"id":"5a0ae037a90746c249b6c1f7" , "value" : "456" }],
"isDeleted" : false
"__v" : 0
}
This is the mongoose data format.
How can i insert data in mongoose like this ?
I am also confused that how should i post data from postman to insert data in this ?
I think your current structure is good just add _id: false to avoid to add auto generated _id in socketValue. like
socketValue: [{
id: String,
data : String,
_id: false
}],
for this structure data will store like:
"socketValue" : [{"id":"5a05855b10600e4aa5b3a48e" , "value" : "123" },{"id":"5a0ae037a90746c249b6c1f7" , "value" : "456" }]"
then you can easily update or add new socketValue. I think this [{..},{..},{..}] is the better structure instead of [[{..}][{..}]] this structure.
and for this structure postman request body should contain like.
{
"userId" : "59eee19696fe6560cd54a081",
"socketValue" : [{"id":"5a05855b10600e4aa5b3a48e" , "value" : "123" },{"id":"5a0ae037a90746c249b6c1f7" , "value" : "456" }]",
"isDeleted" : false
}
and in your server side code just use like
var newSocket = new Socket(req.body); // assume your model name is Socket
newSocket.save();
Your postman input data should be raw json format
{
"userId" : "59eee19696fe6560cd54a081",
"socketValue" : [{"id":"5a05855b10600e4aa5b3a48e" , "value" : "123" },{"id":"5a0ae037a90746c249b6c1f7" , "value" : "456" }]",
"isDeleted" : false
}
Your server code
var insertDoc = new collectionname(details);
inserDoc.save(function (err) {
if (err) {
//callback err
} else {
//callback result
}
});
Considering the following
User collection & sample User document
{
"_id" : ObjectId("575c01f7b8e5999addeb598c"),
"username" : "test.1#gmail.com",
"password" : "<password>",
"firstName" : "Test,
"lastName" : "User"
}
I am trying to run an update request to add an entry in userData.eventData which is meant to be an array
In mongo script I can do
> db.Users.update({_id: ObjectId("575c01f7b8e5999addeb598c")}, {"$addToSet":{"userData.eventData":"My event"}} )
And I have the following result : userData is created as an Object and eventData as a nested Array
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.Users.find({_id: ObjectId("575c01f7b8e5999addeb598c")})
{ "_id" : ObjectId("575c01f7b8e5999addeb598c"), "username" : "test.1#gmail.com", "password" : "<password>", "firstName" : "Test", "lastName" : "User", "userData" : { "eventData" : [ "My event" ] } }
While running the same logic in mongo (using driver version 2.1.21)
// with a properly initialized db object
db.collection("Users").update({"_id" : ObjectId("575c01f7b8e5999addeb598c")}, {"$addToSet": { "userData.eventData": "My Event"}}, function(err, result) {
// do something
});
I receive the following response
result:Object
n:0
nModified:0
ok:1
And indeed the database entry is unchanged.
Is that the way it is meant to behave? I can easily fix this by creating the userData.eventData array but I found disturbing the fact that node's Mongo driver and mongo shell didn't behave the same on this
Thanks in advance for your help & advice
Edit 13/6/16
Mistake was on my side, I missed a 'new' before 'ObjectId(...' in node. With it, it behaves exactly the same as in mongo shell (i.e. 'userData' is created as an Object and it includes 'eventData' array)
No issue, then :)
Update, updates an already existing object in your document.
What you want is insert or use upset which creates a new document when no document matches the query criteria
db.collection.update(
{ name: "Andy" },
{
name: "Andy",
rating: 1,
score: 1
},
{ upsert: true }
);
If you wanted to add an object to your array, you would need $push
// Insert a document in the capped collection
function push (db, collection, search, data, callback) {
db.collection(collection).update(
search, {
$push: data
}, function (err, result) {
console.log("New object pushed");
callback(err);
});
}
Assuming the following schema, I am trying to save some GeoJSON data with Mongoose
var simpleSchema = new Schema({
properties:{
name:String,
surname:String
},
location : {
type : String,
coordinates : [ Number , Number ]
}
});
This is how I try to save the document
var a = new simple({properties:{name:"a", surname:"b"}, location:{type:"Point", coordinates:[1, 0]}}).save(function(err){...});
However, what I am getting in the database is
ObjectId("542da9ab0882b41855ac3be0"), "properties" : { "name" : "a", "surname" : "b" }, "__v" : 0 }
It looks like the whole location tag and data are missing. Is this a wrong way to define a schema or a wrong way of saving the document?
When using a field named type in an embedded object, you need to use an object to define its type or Mongoose thinks you're defining the type of object itself.
So change your schema definition to:
var simpleSchema = new Schema({
properties:{
name:String,
surname:String
},
location : {
type : { type: String },
coordinates : [ Number , Number ]
}
});