Search This Blog
2018/10/08
Javascript : Array - map ,reduce,filter
2018/10/06
REST Based CRUD API for Postgres & Express.js
Lets first create table in database required in article.
create table course(id varchar(50),name varchar(500),primary key(id))
insert into course values(1,'C'),(2,'CPP'),(3,'C#'),(4,'python'),(5,'Ruby')
now create PgUtil.js
const pgp = require('pg-promise')(/* initialization options */);
const cn = {
host: 'localhost', // server name or IP address;
port: 5432,
database: 'sangram',
user: 'xdba',
password: 'sangram'
};
const db = pgp(cn); // database instance;
var PgUtil = {
executeQuery: async function (sqlQuery, callback) {
var result = await db.any(sqlQuery)
console.log(result);
callback(null,result)
},
executeNonQuery: async function (sqlQuery, callback) {
var result = await db.none(sqlQuery)
console.log(result);
callback(null,result)
}
}
module.exports = PgUtil
Inside routes add course.js
var express = require('express');
var router = express.Router();
var PgUtil = require('../PgUtil');
/*getbyid */
router.get('/:id?', function (req, res, next) {
var queryString = ''
if (req.params.id) {
queryString = "select * from course where id= '" + req.params.id + "'"
} else {
queryString = "select * from course "
}
console.log(queryString);
PgUtil.executeQuery(queryString, function (err, data) {
if (err) {
res.json(err);
} else {
res.json(data)
}
})
});
/*update*/
router.put('/:id', function (req, res, next) {
console.log(req.body);
var queryString = "update course set name='" + req.body.Name + "' where id= '" + req.params.id + "'"
PgUtil.executeNonQuery(queryString, function (err, data) {
if (err) {
res.json(err);
} else {
res.json({
"message": "row updated successfully"
})
}
})
});
//insert
router.post('/', function (req, res, next) {
var queryString = "insert into course(id,name) values('" + req.body.Id + "','" + req.body.Name + "')"
console.log(queryString);
PgUtil.executeNonQuery(queryString, function (err, data) {
if (err) {
res.json(err);
} else {
res.json({
"message": "row inserted successfully"
})
}
})
});
/*delete */
router.delete('/:id', function (req, res, next) {
var queryString = "delete from course where id= '" + req.params.id + "'"
console.log(queryString);
PgUtil.executeNonQuery(queryString, function (err, data) {
if (err) {
res.json(err);
} else {
res.json({
"message": "row deleted successfully"
})
}
})
});
module.exports = router;
Now we are done ,run "npm start"
On Postman
1) GET : http://localhost:3000/course
will list all course
2) GET :http://localhost:3000/course/1
will list course with id 1
3) POST:http://localhost:3000/Course
Header:Content-Type:application/json
Body:
{
"Id":"7",
"Name":"Java"
}
will add new course
4)PUT:http://localhost:3000/Course/4
Header:Content-Type:application/json
Body:
{
"Name":"Java"
}
will update course with id 4 its name to java from old value
5) Delete: http://localhost:3000/Course/5
will delete course record with id as 5
Code of this article can be viewed at https://github.com/gitsangramdesai/express-pg-rest
REST Based CRUD API for Mysql & Express.js
CREATE TABLE IF NOT EXISTS `course` ( `Id` varchar(50) NOT NULL, `Name` varchar(500) DEFAULT NULL, PRIMARY KEY (`Id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Add Some Entries into course table
insert into course values(1,'C');
insert into course values(2,'CPP');
insert into course values(3,'C#');
insert into course values(4,'Python');
insert into course values(5,'Ruby');
insert into course values(6,'Java');
create express project by running
express --view=ejs mysqlcrud
install packages with
npm install
Now
dbconnection.js as follows
var mysql = require('mysql');
var connection = mysql.createPool({
host: 'localhost',
user: 'xdba',
password: 'Sangram@123',
database: 'play'
});
module.exports = connection;
Create a folder called models and add file "Course.js" with following content
var db = require('../dbconnection'); //reference of dbconnection.js
var Course = {
getAllCourses: function (callback) {
return db.query("Select * from course", callback);
},
getCourseById: function (id, callback) {
return db.query("select * from course where Id=?", [id], callback);
},
addCourse: function (Course, callback) {
return db.query("Insert into course values(?,?)", [Course.Id, Course.Name], callback);
},
deleteCourse: function (id, callback) {
return db.query("delete from course where Id=?", [id], callback);
},
updateCourse: function (id, Course, callback) {
return db.query("update course set Name=? where Id=?", [Course.Name, id], callback);
}
};
module.exports = Course;
add file course.js in route folder as
var express = require('express');
var router = express.Router();
var Course = require('../models/Course');
/*getbyid */
router.get('/:id?', function (req, res, next) {
if (req.params.id) {
Course.getCourseById(req.params.id, function (err, rows) {
if (err) {
res.json(err);
} else {
res.json(rows);
}
});
}else {
Course.getAllCourses(function (err, rows) {
if (err) {
console.log("error");
res.json(err);
} else {
res.json(rows);
}
});
}
});
/*save new */
router.post('/', function (req, res, next) {
console.log(req.body);
Course.addCourse(req.body, function (err, count) {
if (err) {
res.json(err);
} else {
res.json(req.body);//or return count for 1 & 0
}
});
});
/*delete */
router.delete('/:id', function (req, res, next) {
Course.deleteCourse(req.params.id, function (err, count) {
if (err) {
res.json(err);
} else {
res.json(count);
}
});
});
/*update*/
router.put('/:id', function (req, res, next) {
Course.updateCourse(req.params.id, req.body, function (err, rows) {
if (err) {
res.json(err);
} else {
res.json(rows);
}
});
});
module.exports = router;
in app.js below "var users = require('./routes/users');" add
var course = require('./routes/course');
and in app.js below "app.use('/users', users);" add
app.use('/course', course);
Now we are done ,run "npm start"
On Postman
1) GET : http://localhost:3000/course
will list all course
2) GET :http://localhost:3000/course/1
will list course with id 1
3) POST:http://localhost:3000/Course
Header:Content-Type:application/json
Body:
{
"Id":"7",
"Name":"Java"
}
will add new course
4)PUT:http://localhost:3000/Course/4
Header:Content-Type:application/json
Body:
{
"Name":"Java"
}
will update course with id 4 its name to java from old value
5) Delete: http://localhost:3000/Course/5
will delete course record with id as 5
code sample can be viewed at https://github.com/gitsangramdesai/mysql-crud-express
2018/09/30
Express.js : Mongo as session store
Inside app.js from express.js
just after
var express = require('express');
add
var session = require('express-session');
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);
mongoose.connect('mongodb://localhost/sessionstore', {
});
mongoose.Promise = global.Promise;
const db = mongoose.connection
then at first app.use add
app.use(session({
secret: 'my-secret',
resave: false,
saveUninitialized: true,
store: new MongoStore({ mongooseConnection: db })
}));
inside some route try to save session
req.session.city = 'Mumbai';
req.session.username = 'sangram';
inside another route try to retreive saved value
console.log(req.session.city)
console.log(req.session.username)
to check data is saved in mongo ,connect to mongo and switch database and check
> show collections
sessions
> db.sessions.find().pretty()
{
"_id" : "yAuqRI1gIxFOHUbxpxjGasiK61ZvrWT-",
"session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"},\"city\":\"Mumbai\",\"username\":\"sagar\"}",
"expires" : ISODate("2018-10-14T05:32:38.869Z")
}
Code of article can be viewed at https://github.com/gitsangramdesai/mongo-sessionstore-express
2018/09/23
Node.js:Global objects
modules, functions, strings and object.
a) __filename:absolute path of the current module file
b) _dirname:absolute path of the dir in which executable resides
for test.js inside /home/sangram/workspace/node/global folder.
console.log(__filename);
console.log(__dirname);
sangram@sangram-HP-Laptop-15-bs0xx:~/workspace/node/global$ node test.js
/home/sangram/workspace/node/global/test.js
/home/sangram/workspace/node/global
c) setTimeout(cb, ms):its a global function used to run callback after at least said milliseconds.A timer cannot span more than 24.8 days
inside our test.js
console.log(__filename);
console.log(__dirname);
function Hello(){
console.log( "Hello, World!");
}
setTimeout(Hello, 5000);
console.log("Reached End of File");
running test.js
sangram@sangram-HP-Laptop-15-bs0xx:~/workspace/node/global$ node test.js
/home/sangram/workspace/node/global/test.js
/home/sangram/workspace/node/global
Reached End of File
Hello, World!
d) clearTimeout(t): global function used to stop a timer that was previously created with setTimeout()
inside test.js
console.log(__filename);
console.log(__dirname);
function Hello(){
console.log( "Hello, World!");
}
timer = setTimeout(Hello, 5000);
clearTimeout(timer)
console.log("Reached End of File");
running test.js
sangram@sangram-HP-Laptop-15-bs0xx:~/workspace/node/global$ node test.js
/home/sangram/workspace/node/global/test.js
/home/sangram/workspace/node/global
Reached End of File
we can see "Hello World!" is not printed on console as settimeout timer is cleared in.
e) setInterval:global function used to run callback cb repeatedly after at least ms milliseconds.timer cannot span more than 24.8 days.
inside test.js
console.log(__filename);
console.log(__dirname);
function Hello(){
console.log( "Hello, World!");
}
//timer = setTimeout(Hello, 1);
//clearTimeout(timer)
setInterval(Hello,2000)
console.log("Reached End of File");
running test.js
sangram@sangram-HP-Laptop-15-bs0xx:~/workspace/node/global$ node test.js
/home/sangram/workspace/node/global/test.js
/home/sangram/workspace/node/global
Reached End of File
Hello, World!
Hello, World!
Hello, World!
Hello, World!
^C
f) clearInterval: global function used to stop a timer that was previously created with setInterval()
inside test.js
console.log(__filename);
console.log(__dirname);
function Hello(){
console.log( "Hello, World!");
}
//timer = setTimeout(Hello, 1);
//clearTimeout(timer)
timer2 = setInterval(Hello,2000)
clearInterval(timer2)
console.log("Reached End of File");
running test.js
sangram@sangram-HP-Laptop-15-bs0xx:~/workspace/node/global$ node test.js
/home/sangram/workspace/node/global/test.js
/home/sangram/workspace/node/global
Reached End of File
no "Hello World!" is printed on console.
Global Objects:
Console, Process & Buffer are commonly used global objects in node.js.Console used to print message on stdout and stderr.Process used to get information on current process.
Console has three methods console.log(),console.error() & console.warn() for printing output.
Global modules:
a) OS:
Provides basic operating-system related utility functions.
b) Path:
Provides utilities for handling and transforming file paths.
c) Net :
Provides both servers and clients as streams. Acts as a network wrapper.
d) DNS :
Provides functions to do actual DNS lookup as well as to use underlying operating system name resolution functionalities.
e)Domain:
Provides ways to handle multiple different I/O operations as a single group.
Exploring redis commands - part 2
Max length of list is (2^32 - 1).
127.0.0.1:6379> auth sangram
OK
LPUSH creates list where last pushed element is at index 0.
127.0.0.1:6379> LPUSH subjects english
(integer) 1
127.0.0.1:6379> LPUSH subjects marathi
(integer) 2
127.0.0.1:6379> LPUSH subjects hindi
(integer) 3
127.0.0.1:6379> LPUSH subjects history
(integer) 4
127.0.0.1:6379> LPUSH subjects geography
(integer) 5
127.0.0.1:6379> LPUSH subjects economics
(integer) 6
127.0.0.1:6379> LPUSH subjects maths
(integer) 7
127.0.0.1:6379> LPUSH subjects science
(integer) 8
127.0.0.1:6379> LLEN subjects
(integer) 8
LINDEX get element at specified index in list.
127.0.0.1:6379> LINDEX subjects 0
"science"
127.0.0.1:6379> LINDEX subjects 1
"maths"
127.0.0.1:6379> LINDEX subjects 3
"geography"
BLPOP command removes the first element in a list it returns the first element, if available, or blocks the client for specific time to execute any command.
127.0.0.1:6379> BLPOP subjects 100
1) "subjects"
2) "science"
127.0.0.1:6379> LLEN subjects
(integer) 7
BRPOP removes element from bottom of list.
127.0.0.1:6379> BRPOP subjects 100
1) "subjects"
2) "english"
127.0.0.1:6379> LLEN subjects
(integer) 6
LRANGE prints values in list based on start Index & end Index
127.0.0.1:6379> LRANGE subjects 0 20
1) "mathsssds"
2) "mathss"
3) "maths"
4) "maths"
5) "maths"
6) "english"
7) "maths"
8) "economics"
9) "geography"
10) "history"
11) "hindi"
12) "marathi"
LPUSHX insert push at head of list only if list is already defined.Here "subjectss" is not defined to insertion fails at 1st attempts then succeed.
127.0.0.1:6379> LPUSHX subjectss mathsssds
(integer) 0
127.0.0.1:6379> LPUSH subjectss mathsssds
(integer) 1
127.0.0.1:6379> LPUSHX subjectss mathsssds
(integer) 2
RPUSH -insert at bottom of list
127.0.0.1:6379> RPUSH subjects geometry
(integer) 13
127.0.0.1:6379> LRANGE subjects 0 20
1) "mathsssds"
2) "mathss"
3) "maths"
4) "maths"
5) "maths"
6) "english"
7) "maths"
8) "economics"
9) "geography"
10) "history"
11) "hindi"
12) "marathi"
13) "geometry"
below LREM removes 2 occurances "maths" from list starting search from top to bottom.if instead 2 its negative value say -2 them search start from bottom to top,if instead of 2 its 0 then remove all occurances of search string in list.
127.0.0.1:6379> LRANGE subjects 0 20
1) "mathsssds"
2) "mathss"
3) "maths"
4) "maths"
5) "maths"
6) "english"
7) "maths"
8) "economics"
9) "geography"
10) "history"
11) "hindi"
12) "marathi"
13) "geometry"
127.0.0.1:6379> LREM subjects 2 maths
(integer) 2
127.0.0.1:6379> LRANGE subjects 0 20
1) "mathsssds"
2) "mathss"
3) "maths"
4) "english"
5) "maths"
6) "economics"
7) "geography"
8) "history"
9) "hindi"
10) "marathi"
11) "geometry"
RPUSHX command inserts the value at the bottom of the list only if the list already exists
127.0.0.1:6379> RPUSHX s math
(integer) 0
127.0.0.1:6379> RPUSHX subject math
(integer) 0
127.0.0.1:6379> RPUSHX subjects math
(integer) 8
RPOP removes and return last element from bottom in list
127.0.0.1:6379> LRANGE subjects 0 20
1) "english"
2) "economics"
3) "geography"
4) "history"
5) "hindi"
6) "marathi"
7) "geometry"
8) "math"
127.0.0.1:6379> RPOP subjects
"math"
127.0.0.1:6379> LRANGE subjects 0 20
1) "english"
2) "economics"
3) "geography"
4) "history"
5) "hindi"
6) "marathi"
7) "geometry"
LPOP removes and returns the first element in top list.
127.0.0.1:6379> LRANGE subjects 0 20
1) "english"
2) "economics"
3) "geography"
4) "history"
5) "hindi"
6) "marathi"
7) "geometry"
127.0.0.1:6379> LPOP subjects
"english"
RPOPLPUSH -removes element from bottom of list and insert into new list
127.0.0.1:6379> LRANGE subjects 0 20
1) "economics"
2) "geography"
3) "history"
4) "hindi"
5) "marathi"
6) "geometry"
127.0.0.1:6379> RPOPLPUSH subjects s
"geometry"
127.0.0.1:6379> LRANGE subjects 0 20
1) "economics"
2) "geography"
3) "history"
4) "hindi"
5) "marathi
127.0.0.1:6379> LRANGE s 0 20
1) "geometry"
2018/09/22
Exploring redis commands - part 1
127.0.0.1:6379> ping
PONG
saving key & retreving saved value
127.0.0.1:6379> set mykey myvalue
OK
127.0.0.1:6379> get mykey
"myvalue"
127.0.0.1:6379>
setting password
open "/etc/redis/redis.conf" and look for "requirepass" commented line,uncomment it set password as
requirepass sangram
then we need to restart service
sudo service redis-server restart .now we need to open redis-cli again
on redis-cli we will check password is enforced or not,lets try to set some random key value as follows
127.0.0.1:6379> set mykey test
(error) NOAUTH Authentication required.
Now we will keyin password as follows
127.0.0.1:6379> auth sangram
OK
after getting authenticated we are able to save key
127.0.0.1:6379> set mykey test
OK
Getting config value
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "sangram"
Overrride key
127.0.0.1:6379> set mykey test2
OK
127.0.0.1:6379> get mykey
"test2"
Deleteing key:
127.0.0.1:6379> DEL mykey
(integer) 1
List keys by pattern:
127.0.0.1:6379> set mykey1 test2
OK
127.0.0.1:6379> set mykey2 test2
OK
127.0.0.1:6379> KEYS my*
1) "mykey2"
2) "mykey"
3) "mykey1
List All Keys:
127.0.0.1:6379> KEYS *
1) "mykey2"
2) "mykey"
3) "mykey1"
Expiry:
Redis Expire command is used to set the expiry of a key. After the expiry time, the key will not be available in Redis.It returns 1, if timeout is set for the key else 0.
127.0.0.1:6379> EXPIRE mykey 10
(integer) 1
unit of expiry time is in seconds
checking if key expired
127.0.0.1:6379> KEYS *
1) "mykey1"
2) "mykey2"
3) "\xe2\x80\x9ca-test\xe2\x80\x9d"
4) "a-test"
no occurance of mykey found.
setting key in milli seconds
127.0.0.1:6379> set mykey3 test3 PX 5000
OK
we can also set expiry at the time of adding key
127.0.0.1:6379> set mykey3 test3 EX 10
OK
Check if key exist:returns 1 if key exist else 0.
127.0.0.1:6379> EXISTS mykey3
(integer) 0
127.0.0.1:6379> EXISTS mykey1
(integer) 1
Store Javascript objects in Redis
127.0.0.1:6379> HSET "a-test" "name.first" "Kyle"
(integer) 1
127.0.0.1:6379> HSET "a-test" "name.family" "Davis"
(integer) 1
127.0.0.1:6379> HSET "a-test" "address" "123 Main Street"
(integer) 1
Get value for saved key:
127.0.0.1:6379> HGET "a-test" "name.family"
"Davis"
127.0.0.1:6379> HGET "a-test" "address"
"123 Main Street"
Get value for saved keys:
127.0.0.1:6379> HMGET "a-test" "name.first" "address"
1) "Kyle"
2) "123 Main Street"
this is same as saving below json in javascript world
var aTest = {
"name.first" : ‘Kyle’,
"name.family" : ‘Davis’,
"address" : ‘123 Main Street’
}
Storing multiple key at in one go:
127.0.0.1:6379> HMSET adrees city "mumbai" zip "400074"
OK
127.0.0.1:6379> HGET adrees city
"mumbai"
add key only if key does not exist do not override existing key value
127.0.0.1:6379> HSETNX adrees city "pune"
(integer) 0
127.0.0.1:6379> HSETNX adrees state "maharshtra"
(integer) 1
confirming insertion:
127.0.0.1:6379> HGETALL adrees
1) "city"
2) "mumbai"
3) "zip"
4) "400074"
5) "state"
6) "maharshtra"
removing key:
127.0.0.1:6379> HDEL "a-test" "name.family"
(integer) 1
view complete hash:
127.0.0.1:6379> HGETALL "a-test"
1) "name.first"
2) "Kyle"
3) "address"
4) "123 Main Street"
list all keys only
127.0.0.1:6379> HKEYS "a-test"
1) "name.first"
2) "address"
list all values:
127.0.0.1:6379> HVALS a-test
1) "Kyle"
2) "123 Main Street"
total keys:
127.0.0.1:6379> HLEN "a-test"
(integer) 2
check key exist in hash:
127.0.0.1:6379> HEXISTS "a-test" address
(integer) 1
127.0.0.1:6379> HEXISTS "a-test" addresss
(integer) 0
Database:
In Redis the number of Redis databases is fixed, and set in the configuration file. By default, you have 16 databases. Each database is identified by a number (not a name).
You can use the following command to know the number of databases:
127.0.0.1:6379> CONFIG GET databases
1) "databases"
2) "16"
selecting database of specific number
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> set mykey3 test3
OK
127.0.0.1:6379[1]> KEYS *
1) "mykey3"
on redis-cli switching between databases the key persist.
You can use the following command to list the databases for which some keys are defined:
127.0.0.1:6379> INFO keyspace
# Keyspace
db0:keys=4,expires=0,avg_ttl=0
To get redis backup dir
127.0.0.1:6379> CONFIG get dir
1) "dir"
2) "/var/lib/redis"
Redis SAVE command is used to create a backup of the current Redis database.
127.0.0.1:6379> SAVE
OK
This command will create a dump.rdb file in your Redis directory.
root@sangram-HP-Laptop-15-bs0xx:/home/sangram/workspace/node/hoisting# ls -lth /var/lib/redis/dump.rdb
-rw-rw---- 1 redis redis 358 Sep 22 20:24 /var/lib/redis/dump.rdb
Notice time file has been created.
BGSAVE command will start the backup process and run this in the background.
127.0.0.1:6379> BGSAVE
Background saving started
To restore Redis data, move Redis backup file (dump.rdb) into your Redis backup directory and start the server.
Object.assign in javascipt
Object.assign is used for merging object & cloning purpose.
Merging Objects in JavaScript
var o1 = { a: 1 };
var o2 = { b: 2,a:5 };
var o3 = { c: 3 };
var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 5, b: 2, c: 3 }
console.log(o1); // { a: 5, b: 2, c: 3 }, target object itself is changed.
console.log(o2); // {b: 2,a:5 }
console.log(o3); // { c: 3 }
Here we are merging o1,o2,o3 object during merge o1 also get merged object value along with returned object "obj". 'a' happens to be in o1 & o2 so in merged object a get value from last object with a defined in it based on sequence in which they comes in Object.assign.
Copying Object
Though object.assign copies object deep clone is not happening.
var obj2 = Object.assign({ p: 67 }, { q: 09 }, { r: 34 });
console.log(obj2);
let obj3 = {person: 'Thor Odinson',adr:{city:"mumbai"}};
let clone = Object.assign({}, obj3);
obj3.person ="test"
obj3.adr.city="kolkota"
console.log(clone);
console.log(obj3);
obj3 adr-->city in copied to "clone" by reference unlike key "person".so deep coping is not happening ,change in source adr-->city will modify in cloned object also.
Deep Clone:
let obj4 = {person: 'Thor Odinson',adr:{city:"mumbai"}};
let deep_clone = JSON.parse(JSON.stringify(obj4))
obj4.adr.city="pune"
console.log(deep_clone);
console.log(obj4);
Deep clone is possible using JSON.parse(JSON.stringify()) call on object.
Shallow Copy Example:
var employeeDetailsOriginal = { name: 'Manjula', age: 25, Profession: 'Software Engineer' };
var employeeDetailsDuplicate = employeeDetailsOriginal; //Shallow copy!
employeeDetailsDuplicate.name = 'NameChanged';
console.log(employeeDetailsOriginal);
console.log(employeeDetailsDuplicate);
Output:
{ name: 'NameChanged', age: 25, Profession: 'Software Engineer' }
{ name: 'NameChanged', age: 25, Profession: 'Software Engineer' }
Ellipses in Javascript:
var obj33 =[{a:4,b:7},{p:6,q:5}]
var obj5 = [... obj33];
obj33[0].a =44
console.log(obj5);
console.log(obj33);
object array copied using ellipses syntax also not deep clone.
Copying property by looping:
var person = {
name: 'John',
age: 28,
adr:{state:"maha"}
};
var newPerson = new Object();
for(prop in person){
newPerson[prop] = person[prop];
}
newPerson.adr.state="karnataka"
newPerson.age = 30
console.log(newPerson === person)
console.log(person)
copying property by looping in object also do not deep clone.
2018/09/21
Quering Mongo
db.hc_hosting_stat.aggregate([
{
$project: {
maximum_marks: 1,
'topper': {
$filter: {
input: '$student',
as: 'item',
cond: {
$eq: ['$$item.marks', '$maximum_marks']
}
}
}
}
}
])
Result:
{
"_id" : "geography",
"maximum_marks" : 85.0,
"topper" : [
{
"_id" : ObjectId("5ba49f7da3b0f1fce83f3f41"),
"name" : "sachin",
"marks" : 85.0,
"subject" : "geography"
}
]
}
{
"_id" : "maths",
"maximum_marks" : 90.0,
"topper" : [
{
"_id" : ObjectId("5ba49f90a3b0f1fce83f3f43"),
"name" : "saurabh",
"marks" : 90.0,
"subject" : "maths"
}
]
}
{
"_id" : "marathi",
"maximum_marks" : 85.0,
"topper" : [
{
"_id" : ObjectId("5ba4a1fdffaf9599885ab184"),
"name" : "vivek",
"marks" : 85.0,
"subject" : "marathi"
},
{
"_id" : ObjectId("5ba4a205ffaf9599885ab185"),
"name" : "vijay",
"subject" : "marathi",
"marks" : 85.0
}
]
}
{
"_id" : "english",
"maximum_marks" : 76.0,
"topper" : [
{
"_id" : ObjectId("5ba49f63a3b0f1fce83f3f3f"),
"name" : "sangram",
"marks" : 76.0,
"subject" : "english"
}
]
}
combining two steps into one:
This query list all subject toppers keeping in concern that many student getting top score in a subject.e.g.vivek & vineet both score top in Marathi.
db.maxdemo.aggregate([
{
$group : {
_id : "$subject",
topscore : {$max : "$marks"},
student: {$push: "$$ROOT"}
}
},
{
$project:
{
topscore: 1,
_id:0,
'subject': '$_id',
'topper': {
$filter: {
input: '$student',
as: 'item',
cond: {
$eq: ['$$item.marks', '$topscore']
}
}
}
}
}
])
Result:
{
"topscore" : 85.0,
"subject" : "geography",
"topper" : [
{
"_id" : ObjectId("5ba49f7da3b0f1fce83f3f41"),
"name" : "sachin",
"marks" : 85.0,
"subject" : "geography"
}
]
}
{
"topscore" : 90.0,
"subject" : "maths",
"topper" : [
{
"_id" : ObjectId("5ba49f90a3b0f1fce83f3f43"),
"name" : "saurabh",
"marks" : 90.0,
"subject" : "maths"
}
]
}
{
"topscore" : 85.0,
"subject" : "marathi",
"topper" : [
{
"_id" : ObjectId("5ba4a1fdffaf9599885ab184"),
"name" : "vivek",
"marks" : 85.0,
"subject" : "marathi"
},
{
"_id" : ObjectId("5ba4a205ffaf9599885ab185"),
"name" : "vijay",
"subject" : "marathi",
"marks" : 85.0
}
]
}
{
"topscore" : 76.0,
"subject" : "english",
"topper" : [
{
"_id" : ObjectId("5ba49f63a3b0f1fce83f3f3f"),
"name" : "sangram",
"marks" : 76.0,
"subject" : "english"
}
]
}