Writing mongoDb queries using mongoose to create node api - json

I have some mongoDb collections 'classrooms' and 'students' of the form:
Classrooms:
{
"_id" : ObjectId("56c7219dbd5f92cd78ae4b7e"),
"name" : "My Students",
"user" : ObjectId("56c7218cbd5f92cd78ae4b7c"),
"updatedAt" : ISODate("2016-02-19T14:07:25.965+0000"),
"createdAt" : ISODate("2016-02-19T14:07:25.965+0000"),
"students" : [
ObjectId("56dbb26cff34aa686c0d9d25"),
ObjectId("56f7c2bf1982aa9219ae8843")
],
"role" : "user",
"allowDelete" : false,
"__v" : NumberInt(0)
}
Students:
{
"_id" : ObjectId("56dbb26cff34aa686c0d9d25"),
"email" : "1989manjari#gmail.com",
"createdBy" : ObjectId("56c7218cbd5f92cd78ae4b7c"),
"classRoom" : ObjectId("56c7219dbd5f92cd78ae4b7e"),
"mentorEmail" : "gauravatbits#gmail.com",
"studentId" : ObjectId("56ced54303b7cb7b0eda9862"),
"status" : true,
"updatedAt" : ISODate("2016-03-11T15:32:36.806+0000"),
"autoAdd" : true,
"createdAt" : ISODate("2016-03-06T04:30:36.073+0000"),
"__v" : NumberInt(0)
}
My query is:
id_list = db.classrooms.distinct("students");
db.students.find({_id: {$in: id_list}, studentId:{$exists:false}},{email:1, mentorEmail: 1}).pretty()
Now I want to create an endpoint in node api for this response. So i wanted to know how can I write these queries in Mongoose and create endpoint like: app.get('/api/myquery') to get the json result.
P.S. : Is it possible to do this, without creating schema in Mongoose because i also have some collections which have large no. of fields(38 fields). I just want to get some json data by applying queries in already existing collections.

something like this with mongoose
just pseudo code
var model = mongoose.model("collection", mongooseSchema)
app.get('/api/myquery', function(){
model.find({_id : id_list}, "email mentorEmail", function(err, data){
if(err)throw err;
res.json(data) // maybe use JSON.stringify() if didnt get json but that sets application/json in header of HTTP
})
})

You can directly insert jsons in mongoose but you should keep in mind that only that data will be read which are mentioned in the models in mongoose. Do keeping 38 fields is not a problem just insert in directly.

Related

If then else in json

Set values based on the ip address in JSON with if the else
Using perl JSON module.
I'm trying to setup my etc/config.json so that I never have to edit it when I move code from development->staging->production.
sql ip addresses will be different for different VM's
{
"html_title" : "Bogus",
"local_ip" :
"default" : "[production]",
"hosts" :
{
"production" :
{
"10.11.12.13" : "b102-vm",
"10.11.12.14" : "b103-vm"
},
"stage" :
{
"10.11.12.15" : "b102-vm-s",
"10.11.12.16" : "b103-vm-s"
},
},
"production" :
{
"some_schema" :
{
"host" : "10.11.12.13",
"database" : "some_table",
"dsn" : "DBI:mysql:[production.some_schema.database]:[production.some_schema.host]",
"user" : "user",
"pass" : "pass"
}
},
"stage" :
{
"some_schema" :
{
"host" : "10.11.12.16",
"database" : "some_table",
"dsn" : "DBI:mysql:[stage.some_schema.database]:[stage.some_schema.host]",
"user" : "user",
"pass" : "pass"
}
},
"if" : HERE IS WHERE I GET LOST.
{
"local_ip" : {
"anyOf" : ["[hosts.production]"]
}
},
"then" : { "default" : "[production]" }
"else" :
{
"if" :
{
"local_ip" : {
"anyOf" : ["[hosts.stage]"]
}
},
"then" : { "default" : "[production]" }
}
}
Would like to see "default" point to the production or stage values
As others have pointed out in the comments, JSON is not a programming language; it is a data storage format.
I can think of two obvious ways to do this. Yours is, I'm sorry to say, not one of them.
Both of my solutions involve your various systems having an environment variable set which identifies the kind of environment it is. I'm also going to assume some kind of get_config() function that reads a config file and returns a Perl data structure of the config.
Solution 1: Separate files
Have two files called "staging.json" and "production.json". The get_config() function reads the required one.
sub get_config {
my %valid_env = (
staging => 1,
production => 1,
);
die "$ENV{ENVIRONMENT} is not a valid environment type\n"
unless $valid_env{$ENV{ENVIRONMENT}};
my $json = read_file("$ENV{ENVIRONMENT}.json");
return JSON->new->decode($json);
}
As an extension to this, you could have three files - common.json, staging.json and production.json. You'd always read common.json along with the correct environment file and merge the two data structures into one before returning the data.
Solution 2: Munge the config
Stick with your existing file but munge the data structure after you've read it and before you return it.
sub get_config {
my %valid_env = (
staging => 1,
production => 1,
);
die "$ENV{ENVIRONMENT} is not a valid environment type\n"
unless $valid_env{$ENV{ENVIRONMENT}};
my $json = read_file('config.json');
my $config = JSON->new->decode($json);
# Use $ENV{ENVIRONMENT} to munge the contents of $config
# so it only contains data about the current environment
return $config;
}

Fires query to return a single child and update a value

I have a function that queries Firebase using .queryEqual to get me th node I want to update but I do not know how to set the value to false. Here is the function I have:
func addrShipDefault() {
let ref = Router.addrShip.reference().child(self.userId)
let query = ref.queryOrdered(byChild: "isDefault").queryEqual(toValue: true)
query.setValue(false, "isDefault")
}
Would someone be able to tell me how to query Firebase for the node I am looking for and update its value?
I have done other updates using ref.updateChildValues, but for those I know the exact path. This time I need to lookup the node that has isDefault set to true and modify it.
Hope this makes sense!!
Thank you for the help
**** UPDATE TO SHOW DB STRUCTURE
{
"addr_01" : {
"address1" : "63 Park Ave",
"address2" : "Unit #2",
"city" : "Greenland",
"firstName" : "John",
"id" : "addr_01",
"isDefault" : true,
"lastName" : "Smith",
"state" : "MA",
"zipcode" : "01890"
},
"addr_02" : {
"address1" : "101 Lafayette Rd",
"address2" : "",
"city" : "Rye",
"firstName" : "Say It In 3D",
"id" : "addr_02",
"isDefault" : false,
"lastName" : "",
"state" : "NH",
"zipcode" : "03870"
}
}
From the official documentation here
you can update a child
without rewriting the entire object. If you want to allow users to
update their profiles you could update the username as follows:
self.ref.child("users/(user.uid)/username").setValue(username)
Now using the above example in your case:
We can do something like this: (I havent tried it but I think you can get the idea)
let ref = Router.addrShip.reference().child(self.userId)
let query = ref.queryOrdered(byChild: "isDefault").queryEqual(toValue: true)
//query.child("isDefault").setValue(false)
//Updated Code
query.observeSingleEvent(of: .childAdded) { (snapshot) in
let newRef = snapshot.ref.child("isDefault")
newRef.setValue(false, withCompletionBlock: { (err, ref) in
print("SetValue")
})
}
Note that from official documentation here
Function signature for setValue method is as follows:
func setValue(_ value: Any?)
As can be seen above, it accepts optional of any type value, which means you can pass any value for valid json.
Also note that there is also a method with completion block
func setValue(_ value: Any?, withCompletionBlock block: #escaping (Error?, DatabaseReference) -> Void)

How to use equalTo() query function on a child which is an array

I have a Json Tree for Teachers database
{ "Teachers":
{
"Teacher_id" : {
"email" : "teacher1#something.com",
"name" : "teacher1",
"Subjects" : {0 : "Maths",
1 : "science"
},
"Subject_Exp-in-years" :{ 0:"Maths_2",
1:"Science_4"
}
},
"Teacher_id" : {
"email" : "teacher2#something.com",
"name" : "teacher2",
"Subjects" : {0 : "Geography",
1 : "science"
},
"Subject_Exp-in-years" :{ "Geography_5",
"Science_1"
}
}
}
How can I get Set of Teachers who teach Science
I have used the query
var db_ref=firebase.database().ref();
db_ref.child("Teachers").orderByChild("Subjects").equalTo("Science")
How can I check if a value is present in an array in the database by querying functions?
When using .orderByChild("Subjects").equalTo("Science") doesn't work because none of the Subjects node children is equal to Science. So in order to solve this, I recomand you to change a little bit your database structure like this:
{ "Teachers":
{
"Teacher_id" : {
"email" : "teacher1#something.com",
"name" : "teacher1",
"Subjects" : {Maths: true,
science: true
},
As you can see i have changed the childrens of Subjects with: Maths: true and science: true. To check if a value is present under a node, just use exists() function on that node.
Hope it helps.
You can use for loop to read each of the element in an array.
When you read them one by one, you can include if else statement to check whether the value that you want existed or not. Let,s say the value is JOHN.
var index;
var arraylist = ["a", "b", "c"];
for (index = 0; index < arraylist.length; ++index) {
if(arraylist[index] = "JOHN") {
console.log(arraylist[index] + "is in the array");
};
}

how to insert multiple documents in mongodb into a collection using json.parse()

i have a json file with these data
{
'EDUCATION_ID' : 1,
'CANDIDATE_ID' : 3,
'EDUCATION_TYPE' : "MTech",
'INSTITUTE_NAME' : "IIT Kanpur",
'YEAR_OF_COMPLETION' : 2002,
'CREATE_DT' : "2008-12-06",
'UPD_DT' : null,
'EXPERIENCE' : 8
},
{
'EDUCATION_ID' : 2,
'CANDIDATE_ID' : 5,
'EDUCATION_TYPE' : "MBA",
'INSTITUTE_NAME' : "KIIT Bhubaneshwar",
'YEAR_OF_COMPLETION' : 2000,
'CREATE_DT' : "2001-08-14",
'UPD_DT' : "2004-10-22",
'EXPERIENCE' : 3
}
I am trying to insert these into mongodb using the following code.Only the first document is getting inserted.can any one explain why?,also can anyone suggest any better way to do read from a external file and insert to db.I am new to mongodb.Any suggestions are gladly accepted :)
MongoClient mc=new MongoClient("localhost",27017);
DB db=mc.getDB("mydb");
String file=ReadAndWrite.func2();//i am reading from a external json file
DBObject dbo = (DBObject) JSON.parse(file);
DBCollection dbc=db.getCollection("candidate_education");
dbc.insert(dbo);

ExtJS combobox jsonDataStore

var remoteLookupJsonStore = new Ext.data.JsonStore({
root : 'records',
baseParams : {
column : 'fullName'
},
fields : [
{
name : 'name',
mapping : 'fullName'
},
{
name : 'id',
mapping : 'id'
}
],
proxy : new Ext.data.ScriptTagProxy({
url : 'LookupLoader.ashx'
//url: 'http://tdg-i.com/dataQuery.php' similar data
})
});
var combo2 = {
xtype : 'combo',
fieldLabel : 'Search by name',
forceSelection : true,
displayField : 'name',
valueField : 'id',
hiddenName : 'customerId',
loadingText : 'Querying....',
minChars : 1,
triggerAction : 'name',
store : remoteLookupJsonStore
};
This sample works with the original data store 'http://tdg-i.com/dataQuery.php'. My ashx handler returns data in the same format, but the data is different. Anyhow, when I use my ashx handler, the handler gets invoked, it returns data, but combo always stays in the loading state, and never displays the data.
I am assuming that the problem is with the data I am returning, but its format is fine,the last thing I changed was setting the Content Type
context.Response.ContentType = "application/json";
but I still cannot get this thing to work, any suggestions?
this is data coming from my handler.
({"totalCount": "4","records":[{"id":1,"fullName": "aaa bbb"},{"id":2,"fullName":"cc dd"},{"id":3,"fullName":"ee ff"},{"id":4,"fullName":"gg hh"}]});
Your first record (id 1) is missing "fullName" which makes it invalid JSON -- not sure if that's just an error typing it here or not.
proxy : new Ext.data.ScriptTagProxy({
url : 'LookupLoader.ashx'
//url: 'http://tdg-i.com/dataQuery.php' similar data
})
well looks like for querying same domain, I should be using HttpProxy
so there you have it, that is why it was working with the sample data provided by the web site but not with my local version.