Passing variables into a query in mongoose in the first argument - node.js

I am using MEAN stack, i have an entry like this in my mongodb
{ "_id" : ObjectId("5577467683f4716018db19ed"),
"requestMatrix" : { "1698005072" : { "rideId" : "641719948", "status" :"accepted" },"1698005073" : { "rideId" : "641719545", "status" :"rejected" } },
"partners":[ { "customerNumber" : 1698005072 }, { "customerNumber" : 1698072688 } ]}
I want to query the db to return me this entire document based on whether the status is accepted or rejected.
When I run the below query in a command prompt, i get the expected answer
db.joinedrides.find({'requestMatrix.1698005072.status':"accepted"})
But when i want to do the same from nodeJs, I am stuck as the number 1698005072 in the above query is a variable, i am not able to write a query for that.
tried something like this
var criteria = "'requestMatrix.'"+customerNumber+"'.status'";
JoinedRide.find({criteria:"accepted"},function(err,joinedRides){
})
where customerNumber will vary for different requests, in the above mentioned case its value is 1698005072
Any help is appreciated.

You need to do something like this:
var query = {};
var criteria = "requestMatrix." + customerNumber + ".status";
query[criteria] = "accepted"
JoinedRide.find(query,function(err,joinedRides){
})

Related

Node JS and Firebase Unable to Search Using equal.To()

I've started reading into creating Google Actions using Node.JS/Dialogflow/Firebase.
I have reached a big stumbling block, in trying to get a simple code running that would search a Firebase database for a certain value and then report back. For example from the JSON output, I would like to search for the applicationID and have the age passed back as the output.
I would be extremely grateful if someone can review my code and direct me in the right direction.
Table Structure
{
"groupA" : {
"applications" : {
"100" : {
"age" : 20,
"result" : "pass"
},
"200" : {
"age" : 25,
" result " : "pass"
},
"500" : {
"age" : 20,
" result " : "fail"
}
}
}
}
Node JS
return admin.database().ref('groupA').child('applications').orderByChild('applications').equalTo(500)
.once('value')
.then(acceptedApplicationsSnapshot => {
var id = acceptedApplicationsSnapshot.val().age;
var data = acceptedApplicationsSnapshot.val();
var theAge = acceptedApplicationsSnapshot.child("age").val();
agent.add('some random text' + theAge);
});
Within this example the value 500 should be searched with the age then given as the output.
You're ordering/filtering on property applications, but the value you're passing in is a key. So you'll want to use orderByKey instead of orderByChild:
return admin.database().ref('groupA').child('applications').orderByKey().equalTo(500)
A query may match multiple child nodes, so the above returns a snapshot with a list of results. Even when there's only one result, the query will return a list of one result:
{
"500": {
"age" : 20,
" result " : "fail"
}
}
This means that you'll need to loop over the results in your callback:
acceptedApplicationsSnapshot.forEach(appSnapshot => {
var theAge = appSnapshot.child("age").val();
agent.add('some random text' + theAge)
})
Since you know the exact key of the child node you want, you can also simply keep using child() to access the specific node:
return admin.database().ref('groupA').child('applications').child('500')
This will result in a snapshot of that specific node being returned, instead of the list-with-a-single-child-node of the previous snippet.
{
"age" : 20,
" result " : "fail"
}
And then you can use your existing code to retrieve the age from the snapshot.
To search for the applicationsID=500 and have the age passed back as the output, you can try this.
var db = admin.database();
var ref = db.ref("groupA").child("applications/500").once('value')
.then(function(dataSnapshot){
console.log(dataSnapshot.val().age);
});
More info here.
Edited: This should give you the age, in this case equals 20, for the parameter you pass in applications/500 in the code above.
Let me know if it helps.

Customize query according to the condition mongodb + node.js

I don't know whether I have too much expectation from mongodb, but I have a question here.
Is it possible to customize the query according to a boolean parameter? Firstly, I have looked https://docs.mongodb.com/manual/reference/operator/aggregation/cond/.
But didn't find an example where the condition is up to a another parameter.
Here let me clarify by an example;
Let assume I have a flag parameter. I want to execute two similar queries based on whether its value is true or false.
document is like;
{
"name" : "alex",
"age" : NumberInt(21)
}
{
"name" : "felix",
"age" : NumberInt(14)
}
To be able to look the condition I can break them into two different query as;
if(flag){
db.collection.find({age: "18"})
}else{
db.collection.find({age: "21"})
}
I am looking for something like this;
db.collection.aggregate([
{$cond: [flag,{$match: {age: "18"}} ,{$match: {age: "21"}}]}
])
But this throws an error which is not a surprise.
Is it possible to use $cond and execute two different query? Can a parameter pass in the $cond?
You can generate query first based on your condition then execute that query one time.
var query = {};
if(flag){
query.age = 18;
}else{
query.age = 21;
}
db.collection.find(query, function(err, result) {
if(err) {
// return error
}
console.log(result);
// return result
})

How to add a number to a DynamoDB number set using Node.js

I'm just trying to add a number to a number set in DynamoDB. This expression was working with an untyped list. But to save space since it will just be storing numbers I moved everything to plain number sets. Now no matter how much I tinker with it I can't get it to go through.
var phoneID = req.body.PhoneID;
var category = req.body.ratingCategory;
var ratingToAdd = [Number(req.body.rating)]
var dbparams = {
"TableName": "Venue_Ratings",
Key: {
"PhoneID" : phoneID
},
"UpdateExpression": "SET #categoryName = list_append(#categoryName, :rating)",
"ExpressionAttributeNames" : {
"#categoryName" : category
},
"ExpressionAttributeValues": {
":rating": ratingToAdd
},
"ReturnValues": "ALL_NEW"
};
This error is being thrown An operand in the update expression has an incorrect data type
I have also tried changing the update expression to an ADD expression instead like so ADD #categoryName :rating.
I've tried changing ratingToAdd to a plain number not in an array, a string in an array, and a plain string not in an array.
I'm calling the db using the docClient.update method.
I have verified that the sets in the db are in fact number sets and that they exist.
What am I missing here? Thanks for the help.
The below code should add the number to the Number Set (i.e. DynamoDB data type 'NS').
Use this function with ADD in UpdateExpression:-
docClient.createSet([Number(5)])
Code:-
var params = {
TableName : "Movies",
Key : {
"yearkey" : 2016,
"title" : "The Big New Movie 1"
},
UpdateExpression : "ADD #category :categorySet",
ExpressionAttributeNames: {
'#category' : 'category'
},
ExpressionAttributeValues: {':categorySet' : docClient.createSet( [Number(5)])},
ReturnValues: 'UPDATED_NEW'
};

Need to "build" a "key" name in Mongoskin request

I am working on a Node.js app, using Mongoskin and Express.js.
First, here is a simple overview of the MongoDB collection I'm working with :
db.profiles.find()
{ "_id" : ObjectId("5559e6ad8da0dc030010cf64"),
"userid" : "63e9c530-fd60-11e4-a30c-f3b609480e30",
"emailaddr" : { "value" : "x#y.fr", "share" : false },
"fullname" : { "value" : "Azerty Ytreza", "share" : true },
"telnumber" : { "value" : "0606060606", "share" : true }
As you can see, I'm storing multiple objects, following the same architecture (value + boolean)
Depending on what the user will want to share / don't share anymore, I will need to update the "share" value of the good Object.
First, I can't find out how to modify a value stored in an Object.
Referring to this : Modify nested Object value , I thought I could do like this in my Mongoskin requests :
db.collection.update( { _id:...} , { $set: { some_key.param2 : new_info } }
In this case, Node.js is reporting an error, saying "SyntaxError: Unexpected token '.' ".
The thing is that as I said earlier, depending on what the user will want to modify, I won't modify the same "key".
So, I need to build the key name. Example: if the user wants to modify the "share" value of his email address, I will need to update emailaddr.share. But how can I do this using Mongoskin?
I tried different solutions, but it's impossible to do things like :
var key = "emailaddr",
newVal = "true";
key += ".share";
db.collection.update( { _id: ... } { $set: { key : newval } }
Say you want to change the share status of the fullname property :
> var property = "fullname"
> var value = false
You have to dynamically build the object {"fullname.share": false}ยน :
> var updt = {}
> updt[property + ".share"] = value
Then use that object as the parameter to $set:
> db.test.update({"_id" : ObjectId("5559e6ad8da0dc030010cf64")},
... {$set: updt})
// ^^^^
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
1 As a side note, as explained in the doc the quotes (" or ') are mandatory around the name of an object property if it contains a . -- hence the syntax error you mentioned in your question.

Nodejs mongo return data with pagination information

I am using node and mongo with the native client.
I would like to add pagination to my application.
To get pagination, I need my responses to always return count alongside data
I would like to get something like:
{
count : 111,
data : [ { 'a' : 'only first item was requested' } ]
}
I can do this in mongo
> var guy = db.users.find({}).limit(1)
> guy.count()
11
> guy.toArray()
[
{
"_id" : ObjectId("5381a7c004fb02b10b557ee3"),
"email" : "myEmail#guy.com",
"fullName" : "guy mograbi",
"isAdmin" : true,
"password" : "fe20a1f102f49ce45d1170503b4761ef277bb6f",
"username" : "guy",
"validated" : true
}
]
but when I do the same with nodejs mongo client I get errors.
var cursor = collection.find().limit(1);
cursor.toArray( function(){ .. my callback .. });
cursor.count();
It seems that
count is not defined on cursor
that once I applied toArray on cursor, I cannot use the cursor again
How, using nodejs, can I accomplish the same thing I can with mongo directly?
As others have said, if you want to have a total count of the items and then the data you will need to have two queries, there is no other way. Why are you concerned with creating two queries?

Resources