Data not inserted in the collection - javascript

I am trying to insert document in a collection. The structure of the document looks like this:
[{
"observationNum" : 1231,
"observation_data": [{
"child_id": 1234,
"child_observation_data": [{
"activity_performed": true,
"observation_date": 15062016,
"teacher_id": 6789
}]
}]
}]
To achieve this, I have created 3 models. A Model named child_observation_data containing it's data as shown in the JSON structure above. Another Model named observation_data containing child_id and child_observation_data. I am trying to insert the data in the collection as shown below however the data isn't inserted in the observation_data model and child_observation_data model. What am I doing wrong?
function insertData() {
var childObservationDataModelObject = ChildObservationData.ChildObservationData({"activity_performed": true, "observation_date": "17May2016", "teacher_id":789});
var observationDataModelObject = ObservationData.ObservationData({"child_id" : 21386, "child_observation_data":childObservationDataModelObject});
var activityModelObject = new ActivityModel({"observationNumber" : 123456, "observation_data": observationDataModelObject});
activityModelObject.save(function(err, savedObject) {
if(err) {
console.error("error in saving:", err);
return;
}
if(savedObject != null)
console.log("Data saved ", savedObject);
});
ObservationData.getObservationDataModel()
.findOne({"child_id" : 21386})
.populate('child_observation_data')
.exec(function (err, activity) {
if (err)
console.log("error in finding", err);
console.log('The creator is ', activity);
});
}
The console logs are:
Data saved { observation_data: [ 57eb905265ddc958133ac649 ],
_id: 57eb905265ddc958133ac64a,
observationNumber: 123456,
__v: 0 }
The creator is null

Related

How Do I Update An Object in Mongoose?

I have been facing some problem while updating the data in the db using mongoose, Therefore thanks in advance for the help.
I have been sending some data from a dynamic form that contains different set of fields each time... but when i update the array in the db it changes those fields.
This was my controller function earlier:-
exports.savePageContent = (req, res, next) => {
const id = req.body.dest; // getting page data document id
delete req.body.dest;
var arr = [];
// When we are returning the same page each time after we submit the data for the particuklar section form then how are we supposed to redirect the user to next page once he is done doing all
var fieldKeys = Object.keys(req.body);
for(let i = 0; i < fieldKeys.length; i++)
{
arr.push({fieldRef : fieldKeys[i], fieldValue : req.body[fieldKeys[i]]});
}
pageDataModel.findByIdAndUpdate(id, {pageData : arr}).exec(function(err, result) {
if(err){
console.log(err);
}
else {
console.log("data is inserted");
req.flash('message', "Data Saved Successfully");
}
})
}
I also tried a few updates and then moved to this portion
This is my new controller function :
exports.savePageContent = (req, res, next) => {
const pageid = req.body.dest; // getting page data document id
delete req.body.dest;
var fieldRefData = "";
var fieldValueData = "";
var fieldKeys = Object.keys(req.body);
for(let i = 0; i < fieldKeys.length; i++)
{
fieldRefData = fieldKeys[i];
fieldValueData = req.body[fieldKeys[i]];
try{
pageDataModel.update({id : pageid, "pageData.fieldRef" : fieldRefData}, {$set : {"pageData.$.fieldValue" : fieldValueData }}, {upsert : true}).exec(function(err, result) {
if(err){
console.log(err);
}
else {
console.log("data is inserted", result);
}
});
req.flash('message', "Data Saved Successfully");
}catch(e){
console.log(e);
req.flash('message', "error Occurred updating Data ");
}
}
}
To elaborate the case for better understanding:-
This is the data that comes first time in the body
[
{ fieldRef: 'sec1.1.h1', fieldValue: 'this is the field value 1' },
{ fieldRef: 'sec1.1.p', fieldValue: 'this is the field value 1' },
{ fieldRef: 'sec1.1.a', fieldValue: 'this is the field value 1' },
{ fieldRef: 'sec1.2.h2', fieldValue: 'this is the field value 1' }
]
and This is the data that comes the second time :-
[
{ fieldRef: 'sec2.1.h1', fieldValue: 'this the field value 2' },
{ fieldRef: 'sec2.1.p', fieldValue: 'this the field value 2' },
{ fieldRef: 'sec2.1.a', fieldValue: 'this the field value 2' },
{ fieldRef: 'sec2.2.h1', fieldValue: 'this the field value 2' }
]
when i want both the data's in the db but when i send one the second data the first one gets updated to the second one and vice versa..
this is the db images of the scenario
this is the data in the document on the first operation
this is the data in the document on the second operation
i am not able to keep and update them both... so please help me ...
This is the error that I am getting most of the time which says that the query is wrong
MongoServerError: The positional operator did not find the match needed from the query.
at /home/pushkar/Desktop/NodejsWebApp1/node_modules/mongodb/lib/operations/update.js:80:33
at /home/pushkar/Desktop/NodejsWebApp1/node_modules/mongodb/lib/cmap/connection_pool.js:272:25
at handleOperationResult (/home/pushkar/Desktop/NodejsWebApp1/node_modules/mongodb/lib/sdam/server.js:370:9)
at MessageStream.messageHandler (/home/pushkar/Desktop/NodejsWebApp1/node_modules/mongodb/lib/cmap/connection.js:479:9)
at MessageStream.emit (events.js:400:28)
at processIncomingData (/home/pushkar/Desktop/NodejsWebApp1/node_modules/mongodb/lib/cmap/message_stream.js:108:16)
at MessageStream._write (/home/pushkar/Desktop/NodejsWebApp1/node_modules/mongodb/lib/cmap/message_stream.js:28:9)
at writeOrBuffer (internal/streams/writable.js:358:12)
at MessageStream.Writable.write (internal/streams/writable.js:303:10)
at Socket.ondata (internal/streams/readable.js:731:22) {
index: 0,
code: 2
}
Also if I was unable to make my scenario clear please leave a comment and I will try to explain it more clearly..
thanks In Advance
I hope this should solve the issue :
pageDataModel.updateOne({_id : "61d73f31cb5681b85618995a", "pageData.fieldRef" : "sec2.c" },{"$set" : {"pageData.$.fieldValue" : "Mkc" }}).exec(function(err, result) {
if(err) throw err;
else {
console.log(result);
}
});
$set will replace a new value for the key. If you use the 3rd value then the $set will replace the 3rd value, use $push instead of $set operator.https://docs.mongodb.com/manual/reference/operator/update/push/
Try using _id instead of id.
pageDataModel.update({_id : pageid, "pageData.fieldRef"}) {
Or even pageData._id instead of id.
pageDataModel.update({'pageData._id' : pageid, "pageData.fieldRef"}) {
Furthermore, your id is a string in the query, but an object id in database, so call a helper.
pageDataModel.update({'pageData._id' : mongoose.Types.ObjectId(pageid), "pageData.fieldRef"}) {

DynamoDB InvalidParameterType Error While Trying To Put A New Item

I am trying to implement a DynamoDB based application to store some request data. I read the DynamoDB official documentation and currently I am following this official tutorial to do some basic operations.
I am using a local DynamoDB docker container. You can run it with this:
docker run -d -p 8000:8000 amazon/dynamodb-local:latest -jar DynamoDBLocal.jar -sharedDb
When I try to create a new table just same as the tutorial I gave above, I got no error, everything is fine:
var params = {
TableName: 'book',
KeySchema: [
{
AttributeName: 'title',
KeyType: 'HASH',
}
],
AttributeDefinitions: [
{
AttributeName: 'title',
AttributeType: 'S'
}
],
ProvisionedThroughput: {
ReadCapacityUnits: 1,
WriteCapacityUnits: 1,
}
};
dynamodb.createTable(params, function(err, data) {
if (err) print(err); // an error occurred
else print(data); // successful response
});
But when I try to put some new items in it:
var params = {
TableName: 'book',
Item: { // a map of attribute name to AttributeValue
title: "Sample Application: CloudList",
chapter: 10
}
};
dynamodb.putItem(params, function(err, data) {
if (err) print(err); // an error occurred
else print(data); // successful response
});
I got this error:
31 validation error actually is equal to number of chars in title: Sample Application: CloudList. DynamoDB shell also did not recognized the print function which is given in the above tutorial. So I had to replace it with ppJson function. Where am I doing wrong and how can I put/delete/get items from DynamoDB via Web Shell? (and also via PHP code)
Edit: I also tried what Vikdor said in the comment, it seems I got rid of that UnexpectedParameter error but this time I got Invalid attribute value type error.
var params = {
TableName: 'book',
Item: { // a map of attribute name to AttributeValue
'title': {S: "Sample Application: CloudList"},
'chapter': {N: '10'}
}
};
This doc explains the structure of the Item key in the params passed to the API and your params should be as follows:
var params = {
TableName: "book",
Item: {
"title": {"S": "Sample Application: CloudList"},
"chapter": {"N": :10"}
}
};
Note that even the numbers should be enclosed in quotes.

How to search all keys inside MongoDB collection using only one keyword

Is there a way for MongoDB to search an entire collection's keys' contents using only a single search keyword?
Suppose I have the following collection (let's call it foodCollection):
{
name: "Chocolate Mousse Cake",
type: "Cake"
},
{
name: "Mother's Cookies",
type: "Cookies"
},
{
name: "Dark Bar",
type: "Chocolate"
}
I want my search to look for matches that contain "Chocolate", meaning it should return "Chocolate Mousse Cake" and "Dark Bar".
I'm trying to do this using the ff: code:
Client-side controller
// Search Products
$scope.searchProduct = function () {
$http.get('/api/products/search/' + $scope.searchKeyword).success(function(data){
console.log(data);
})
.error(function(err) {
console.log("Search error: " + err);
});
}
Express.js
app.get('/api/products/search/:param', productController.search); // Search for product
Server-side controller (I used this reference from the MongoDB docs):
// Search
module.exports.search = function(req, res) {
console.log("node search: " + req.body);
Product.find({ $or: [{productName: req.body},
{productType: req.body}]
}, function(err, results) {
res.json(results);
});
}
When I executed this, I got nothing. Am I missing something?
Any help would be greatly appreciated. Thank you.
UPDATE (FINAL)
Finally solved this thanks to Joydip's and digit's tips. Here's my solution in case somebody else gets the same problem as I did:
Client-side controller
$scope.searchProduct = function () {
if ($scope.searchKeyword == '') {
loadFromMongoDB(); // reloads original list if keyword is blank
}
else {
$http.get('/api/products/search/' + $scope.searchKeyword).success(function(data){
if (data.length === 0) {
$scope.showNoRec = true; // my flag that triggers "No record found" message in UI
}
else {
$scope.showNoRec = false;
$scope.productList = data; // passes JSON search results to UI
}
});
}
}
Express.js
app.get('/api/products/search/:keyword', productController.search); // Search for product
Mongoose schema
var mongoose = require('mongoose');
var schema = new mongoose.Schema({
productName: String,
productType: String,
productMaker: String,
productPrice: Number,
createDate: Date,
updateDate: Date
});
schema.index({productName: "text", productType: "text", productMaker: "text"});
Server-side controller
module.exports.search = function(req, res) {
Product.find({$text: {$search : req.params.keyword}}, function(err, results){
res.json(results);
})
}
Thank you everyone for your help. :)
You can try by creating an Index:
db.yourollection.createIndex({"productName":1,"productType":1})
And then by searching for the value, Example:
Product.find({$text:{$search: 'Chocolate'}},{productName:1, productType:1});
If you want to search all key, then you can use
db.foodCollection.createIndex( { name: "text", description: "text" } )
then search by
db.foodCollection.find({ $text: { $search: "choco" } })

Meteor publication Exception: Did not check() all arguments during publisher when using aldeed:tabular

I have the following publication:
Meteor.publish( 'usersadmin', function() {
return Meteor.users.find( {}, { fields: { "emails": 1, "roles": 1, "profile": 1 } } )
});
and I'm displaying the publication in the following table using aldeed:tabular:
TabularTables.UsersAdmin = new Tabular.Table({
name: "User List",
collection: Meteor.users,
pub: "usersadmin",
allow: function(userId) {
return Roles.userIsInRole(userId, 'admin');
},
columns: [{
data: "emails",
title: "Email",
render: function(val, type, doc) {
return val[0].address;
}
}, {
data: "roles",
title: "Roles",
render: function(val, type, doc) {
return val[0]._id;
}
}]);
The table displays fine, but in the server terminal the following exception shows up:
Exception from sub usersadmin id 2d7NFjgRXFBZ2s44R Error: Did not check() all arguments during publisher 'usersadmin'
What causes this?
You receive this error because you need to check the arguments passed to your usersadmin publish function by using check(value, pattern).
The reactive DataTables, implemented in the aldeed:tabular package, pass the arguments tableName, ids and fields to the publish function; that's why an exception is thrown.
According to the documentation, you need to take care of the following requirements:
Your function:
MUST accept and check three arguments: tableName, ids, and fields
MUST publish all the documents where _id is in the ids array.
MUST do any necessary security checks
SHOULD publish only the fields listed in the fields object, if one is provided.
MAY also publish other data necessary for your table
This should fix the error:
Meteor.publish('usersadmin', function(tableName, ids, fields) {
check(tableName, String);
check(ids, Array);
check(fields, Match.Optional(Object));
return Meteor.users.find({}, {fields: {"emails": 1, "roles": 1, "profile": 1}});
});

Issue in creating another collection from result of a mongodb query in node

I was trying to create another collection with the result of a query in mongodb using nodejs
The code is working fine if I have only a few number of records. But not working if there is large records.
Error
[Error: Document exceeds maximum allowed bson size of 16777216 bytes]
Code
MongoClient.connect(MONGODB_URI, function (err, database) {
if (err) throw err;
coll = database.collection("smmc_queue");
coll.insert({
"startTime": moment().format("DD-MM-YYYY, h:mm:ss a"),
"caseName": req.body.caseName,
"author": req.session.user,
"jobType": 'Query',
"status": 'In progress',
"searchDescription": searchDescription,
"query": searchCondition,
"sort": sortCondition
}, function (err, sucessDoc) {
res.redirect(302, '/queryStatus');
MongoClient.connect(MONGODB_URI, function (err, database) {
if (err) throw err;
collection = database.collection(req.body.caseName);
collection.find(searchObj, sortObj).toArray(function (err, doc) {
var ncn = 'query_' + sucessDoc[0]._id.toString();
if (!err) {
coll.update({
"_id": sucessDoc[0]._id
}, {
$set: {
"endTime": moment().format("DD-MM-YYYY, h:mm:ss a"),
status: "Completed",
}
}, {
upsert: true,
multi: true
}, function (err, result) {});
resultCollection = database.collection(ncn);
console.log(typeof doc)
console.log(doc.length)
resultCollection.insert(doc, function (err, res) {
console.log(err);
});
} else {
coll.update({
"_id": sucessDoc[0]._id
}, {
$set: {
"endTime": moment().format("DD-MM-YYYY, h:mm:ss a"),
status: "Completed",
"result": err
}
}, {
upsert: true,
multi: true
}, function (err, result) {});
}
});
});
});
})
Console Samples
Search Query : { CARDNO: 821 }
typeof doc : object
doc.length : 756
err (insert to resultCollection) : null
Search Query : { IODATE: { '$gt': Mon Apr 02 2012 00:00:00 GMT+0530 (IST) } }
typeof doc : object
doc.length : 374010
err (insert to resultCollection) : [Error: Document exceeds maximum allowed bson size of 16777216 bytes]
Where did I go wrong?
The reason this fails is because when you are inserting your doc value is an array, of the "lengths" that you are reporting.
While an array of documents is fine to issue to insert, it is not the "individual" document size that is in question, but the whole insert. So you are breaking the maximum BSON size, because the "request" to insert is larger than the maximum (16MB).
What you need to do is break this up, try amounts of 500 at a time.
var last = 0;
for ( var i=0; i < doc.length; i+= 500 ) {
resultCollection.insert( doc.slice(last, i) );
last = i;
}
resultCollection.insert( doc.slice(last, doc.length) );
Or something possibly better than that.
But generally, break up the array. You can only do the limit (16MB) per request.

Categories

Resources