SlideShare a Scribd company logo
COMPARING
MONGODB SEARCH
WITH
RACLE SQL QUERIES
MongoDB Find & Aggregate vs
comparable Oracle SQL queries
Lucas Jellema
O
TOPICS
• Filter & Sort (find, sort)
• Aggregation ($group, $project, $match, $sort)
• Lookup & Outer Join ($lookup, $arrayElemAt)
• Facet Search ($facet, $bucket, $sortByCount)
• Update (findAndModify, forEach, save, update, upsert, $set, $unset)
• Date and Time operations
• Materialized View ($out)
• Nested documents/tables ($unwind, $reduce)
• Geospatial (ensureIndex, 2dsphere, $near, $geoNear)
• Text Search (createIndex, text, $text, $search)
• Stored Procedures (db.system.js.save, $where)
DATA SET
• HRM
• Collections emp and dept – JSON documents in MongoDB database
• Tables EMP and DEPT – relational records in Oracle Database
HRM DATA SET
JSON DOCUMENT COLLECTIONS EMP AND DEPT
HRM DATA SET
TABLES EMP AND DEPT
ALL SOURCES ARE AVAILABLE ON GITHUB
• https://github.com/lucasjellema/sig-nosql-mongodb
FIND THE NAMES OF ALL MANAGERS
db.emp.find
( {"JOB":"MANAGER"}
, {ENAME:1}
)
select ename
from emp
Where job = 'MANAGER'
FIND NAME AND SALARY OF SALESMEN ORDERED BY
SALARY FROM HIGH TO LOW
db.emp.find
( {"JOB":"SALESMAN"}
, { ENAME:1
, SAL:1}
)
.sort
( {'SAL':-1})
select ename
, sal
from emp
where job = 'SALESMAN'
order
by sal desc
FIND NAME AND SALARY OF TWO HIGHEST EARNING
SALESMEN – BEST PAID FIRST
db.emp.find
( {"JOB":"SALESMAN"}
, { ENAME:1
, SAL:1}
)
.sort
( {'SAL':-1})
.limit(2)
select ename
, sal
from emp
where job = 'SALESMAN'
order
by sal desc
FETCH FIRST 2 ROWS ONLY
FIND EMPLOYEES WITH ‘AR’ IN THEIR NAME – IN
ALPHABETICAL ORDER BY NAME
db.emp.find
( {"ENAME":{$regex: "AR"} }
, { ENAME:1
, SAL:1}
)
.sort
( {'ENAME':1})
select ename
, sal
from emp
where ename like '%AR%'
order
by ename
FIND EMPLOYEES NOT IN DEPARTMENT 10, NAME AND
SALARY AND SORTED ALPHABETICALLY BY NAME
db.emp.find
( { "DEPTNO":{$ne: 10} }
, { ENAME:1
, SAL:1
, DEPTNO:1
}
)
.sort
( {'ENAME':1})
select ename
, sal
, deptno
from emp
where deptno != 10
order
by ename
SET DATE TYPE PROPERTY STARTDATE DERIVED FROM
STRING TYPE PROPERTY HIREDATE
db.emp.find().forEach
( function (elem) {
elem.startdate =
new Date( "19“
+ elem.HIREDATE.substring(6)
+ "-"
+ elem.HIREDATE.substring(3,5)
+ "-"
+ elem.HIREDATE.substring(0,2)
);
db.emp.save(elem);
}
)
alter table emp
add (startdate date)
update emp
set startdate =
to_date( hiredate, 'DD-MM-RR')
FIND SALESMEN WITH A TOTAL INCOME HIGHER THAN 2000
-- use $where with embedded JavaScript
db.emp.find
( {"JOB":"SALESMAN"
, $where :
" this.SAL +
(this.COMM != null? this.COMM: 0)
> 2000"
}
)
select *
from emp
where sal + nvl(comm, 0) > 2000
CREATE STORED FUNCTION SALARY CAP TO RETURN MAX SALARY PER
JOB; USE SALARY CAP TO FIND EMPLOYEES EARNING OVER THEIR CAP
db.system.js.save({
"_id": "salaryCap",
"value": function(job) {
return job=='CLERK'?1000
:(job=='ANALYST'?3500
:(job=='SALESMAN'?2000
:(job=='MANAGER'?3000
:10000
)));
}
})
-- load function in current database
db.loadServerScripts();
db.emp.find(
{ $where : " this.SAL >
salaryCap(this.JOB)"}
, {ENAME:1, SAL:1, JOB:1})
create or replace
function salary_cap
(p_job in varchar2)
return number
is
begin
return
case p_job
when 'CLERK' then 1000
when 'ANALYST' then 3500
when 'SALESMAN' then 2000
when 'MANAGER' then 3000
else 10000
end;
end salary_cap;
select ename
, sal
, job
from emp
where sal > salary_cap( job)
SELECT NAME, STARTMONTH AND STARTYEAR FOR ALL
EMPLOYEES
db.emp.aggregate(
[{$project: {
"ENAME": 1,
"startmonth": { $month: "$startdate"},
"startyear": { $year: "$startdate"}
}
}
]
)
select ename
, extract (month from startdate)
as startmonth
, extract (year from startdate)
as startyear
from emp
TOTAL SALARY SUM, TOTAL NUMBER OF EMPLOYEES, THE
HIGHEST SALARY AND THE EARLIEST STARTDATE
db.emp.aggregate(
[{$group: {
_id: null,
total_salary_sum: { $sum: "$SAL" },
total_staff_count: { $sum: 1 },
max_sal: { $max: "$SAL" },
min_startdate: { $min: "$startdate" }
}
}
]
)
select sum(sal) total_salary_sum
, count(*) total_staff_count
, max(sal) max_sal
, min(startdate) min_startdate
from emp
TOTAL SALARY SUM, TOTAL NUMBER OF EMPLOYEES, THE HIGHEST
SALARY AND THE EARLIEST STARTDATE PER DEPARTMENT
db.emp.aggregate(
[{$group: {
_id: "$DEPTNO",
total_salary_sum: { $sum: "$SAL" },
total_staff_count: { $sum: 1 },
max_sal: { $max: "$SAL" },
min_startdate: { $min: "$startdate" }
}
}
]
)
select deptno
, extract (year from startdate)
hireyear
, sum(sal) total_salary_sum
, count(*) total_staff_count
, max(sal) max_sal
, min(startdate) min_startdate
from emp
group
by deptno
, extract (year from startdate)
TOTAL SALARY SUM, NUMBER OF EMPLOYEES, HIGHEST SALARY AND
EARLIEST STARTDATE PER DEPARTMENT AND HIREYEAR
WITH NUMBER OF EMPLOYEES TWO OR MORE
db.emp.aggregate(
[{$group: {
_id: { deptno: "$DEPTNO“
, hireyear :
{ $year: "$startdate"}
},
total_salary_sum: { $sum: "$SAL" },
total_staff_count: { $sum: 1 },
max_sal: { $max: "$SAL" },
min_startdate: { $min: "$startdate" }
}
}
,{$match: {
total_staff_count: { $gt: 1 }
}
}
]
)
select deptno
, extract (year from startdate)
hireyear
, sum(sal) total_salary_sum
, count(*) total_staff_count
, max(sal) max_sal
, min(startdate) min_startdate
from emp
having count(*) > 1
group
by deptno
, extract (year from startdate)
ALL EMPLOYEES WITH THEIR DEPARTMENT DETAILS (WHEN
AVAILABLE)
db.emp.aggregate(
[{$lookup: {
from:"dept",
localField:"DEPTNO",
foreignField:"deptno",
as:"dept"
}
,{$project: {
"EMPNO": 1,
"ENAME": 1,
"DEPT": { $arrayElemAt:["$dept", 0]}
}
}
]
)
select e.*
, d.*
from emp e
left outer join
dept d
on (e.deptno = d.deptno)
ALL DEPARTMENTS WITH A LIST OF THE NAMES OF THEIR EMPLOYEES
db.dept.aggregate(
[{$lookup: {
from:"emp",
localField:"deptno",
foreignField:"DEPTNO",
as:"emps"
}
}
,{$project: {
"deptno": 1,
"dname": 1,
"staff": {
$reduce: {
input: "$emps",
initialValue: "",
in: { $concat : ["$$value"
, ", "
,"$$this.ENAME"]
}
} // reduce
} // staff
} // project
}
])
select d.deptno, d.dname
, listagg( ename, ',')
within group (order by ename)
as "staff"
from dept d
left outer join
emp e
on (d.deptno = e.deptno)
group
by d.deptno
, d.dname
ALL EMPLOYEES WHO WORK IN NEW YORK
db.emp.aggregate(
[{$lookup: {
from:"dept",
localField:"DEPTNO",
foreignField:"deptno",
as:"dept"
}
,{$project: {
"EMPNO": 1,
"ENAME": 1,
"DEPT": { $arrayElemAt:["$dept", 0]}
}
}
, {$match: { "DEPT.loc" :"NEW YORK"} }
]
)
select e.*
, d.*
from emp e
left outer join
dept d
on (e.deptno = d.deptno)
where d.loc = 'NEW YORK'
EMPLOYEE NAMED KING
WITH ALL EMPLOYEES WHO WORK UNDER HER OR HIM
AND A NEAT LIST OF THE NAMES OF THESE SUBORDINATE STAFF
db.emp.aggregate(
[{$match: { ENAME: "KING"}}
,{$lookup: {
from:"emp",
localField:"EMPNO",
foreignField:"MGR",
as:"subordinates"
}
}
,{$project: {
"EMPNO": 1,
"ENAME": 1,
"subordinates": 1,
"staff": { $reduce: {
input: "$subordinates",
initialValue: "",
in: { $concat :
["$$value", ", ","$$this.ENAME"]
} //in
} // reduce
},
}
}
]
)
select e.*
, cursor( select *
from emp s
where s.mgr = e.empno
) subordinates
, ( select listagg( s.ename, ',')
within group
(order by ename)
from emp s
where s.mgr = e.empno
) as "staff"
from emp e
where e.ename = 'KING'
FACET AGGREGATION: # EMPLOYEES BY JOB, BY SALARY BUCKET, BY
DEPARTMENT AND BY STARTDATE (1)
db.emp.aggregate(
[{$facet: {
"categorizedByJob": [
{ $sortByCount: "$JOB" }
],
"categorizedBySalary": [
{$bucket: {
groupBy: "$SAL",
boundaries: [0, 1000, 2000 ,3000 ,10000 ],
default: "Other",
output: {
"count": { $sum: 1 },
"employees": { $push: "$ENAME" }
} // output
}// bucket
}
],
"categorizedByDepartment": [
{ $sortByCount: "$DEPTNO" }
],
"categorizedByHiredate(Auto)": [
{
$bucketAuto: {
groupBy: "$startdate",
buckets: 4
}
}
]
}
}
])
-- categorizedByJob
select job
, count(*) as "count"
from emp
group
by job
order
by "count" desc
-- categorizedByDepartment
select deptno
, count(*) as "count"
from emp
group
by deptno
order
by "count" desc
FACET AGGREGATION: # EMPLOYEES BY JOB, BY SALARY BUCKET, BY
DEPARTMENT AND BY STARTDATE (2)
db.emp.aggregate(
[{$facet: {
"categorizedByJob": [
{ $sortByCount: "$JOB" }
],
"categorizedBySalary": [
{$bucket: {
groupBy: "$SAL",
boundaries: [0, 1000, 2000 ,3000 ,10000 ],
default: "Other",
output: {
"count": { $sum: 1 },
"employees": { $push: "$ENAME" }
} // output
}// bucket
}
],
"categorizedByDepartment": [
{ $sortByCount: "$DEPTNO" }
],
"categorizedByHiredate(Auto)": [
{
$bucketAuto: {
groupBy: "$startdate",
buckets: 4
}
}
]
}
}
])
-- categorizedBySalary
with bucket_boundaries as
( select 10000 lower_boundary from dual
union all
select 2000 lower_boundary from dual
union all
select 3000 lower_boundary from dual
union all
select 10000 lower_boundary from dual
)
, buckets as
( select lower_boundary
, lead(lower_boundary) over
(order by lower_boundary)-1 upper_boundary
from bucket_boundaries
)
select lower_boundary
, count(*)
from emp
left outer join
buckets
on (sal between lower_boundary
and upper_boundary)
group
by lower_boundary
FACET AGGREGATION: # EMPLOYEES BY JOB, BY SALARY BUCKET, BY
DEPARTMENT AND BY STARTDATE (3)
db.emp.aggregate(
[{$facet: {
"categorizedByJob": [
{ $sortByCount: "$JOB" }
],
"categorizedBySalary": [
{$bucket: {
groupBy: "$SAL",
boundaries: [0, 1000, 2000 ,3000 ,10000 ],
default: "Other",
output: {
"count": { $sum: 1 },
"employees": { $push: "$ENAME" }
} // output
}// bucket
}
],
"categorizedByDepartment": [
{ $sortByCount: "$DEPTNO" }
],
"categorizedByHiredate(Auto)": [
{
$bucketAuto: {
groupBy: "$startdate",
buckets: 4
}
}
]
}
}
])
-- categorizedByHiredate
with tiled as
( select ename
, startdate
, ntile(4) over (order by startdate asc)
as size_bucket
from emp
)
select size_bucket
, count(*) as "count"
, listagg( ename, ',')
within group (order by startdate) employees
from tiled
group
by size_bucket
order
by size_bucket
CREATE MATERIALIZED COLLECTION FROM QUERY
DEPARTMENTS WITH NESTED EMPLOYEES
db.dept.aggregate(
[ {$lookup:
{
from:"emp",
localField:"deptno",
foreignField:"DEPTNO",
as:"emps"
}
}
, {$out: "departments"
}
]
)
create or replace type emp_t as object
( EMPNO NUMBER(4)
, ENAME VARCHAR2(10)
, JOB VARCHAR2(9)
, MGR NUMBER(4)
, SAL NUMBER(7,2)
, COMM NUMBER(7,2)
, STARTDATE DATE
)
create or replace type emp_tbl_t as table of emp_t
-- create materialized view
-- with nested table
create materialized view departments
BUILD IMMEDIATE
REFRESH FORCE
ON DEMAND
as
select deptno
, dname
, loc
, cast ( multiset ( select empno, ename, job
, mgr, sal, comm, hiredate
from emp e
where e.deptno = d.deptno
)
as emp_tbl_t) staff
from dept d
FIND DEPARTMENT THAT CONTAINS EMPLOYEE NAMED KING
FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES
db.departments.find
( {"emps.ENAME":"KING"}
)
select d.deptno
, d.dname
, d.loc
from departments d
where ( select count(*)
from table(d.staff)
where ename ='KING'
) > 0
ONLY FIND EMPLOYEE KING (AND NOT ALL EMPLOYEES IN THE DEPARTMENT)
FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES
db.departments.aggregate(
[
{$unwind: {path:"$emps"}}
, {$match: { "emps.ENAME": "KING"}}
, {$project: {
"EMPNO": "$emps.EMPNO",
"JOB": "$emps.JOB",
"ENAME": "$emps.ENAME",
"STARTDATE": "$emps.startdate",
"DNAME": 1
}
}
]
)
select d.deptno
, d.dname
, d.loc
, staff.*
from departments d
, table(d.staff) staff
where staff.ename = 'KING'
FIND NAMES OF ALL MANAGERS
FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES
db.departments.aggregate(
[
{$unwind: {path:"$emps"}}
, {$match: { "emps.JOB": "MANAGER"}}
, {$project: {
"ENAME": "$emps.ENAME",
}
}
]
)
select staff.ename
from departments d
, table(d.staff) staff
where staff.job = 'MANAGER'
FIND ALL EMPLOYEES WHO ARE NOT IN DEPARTMENT 10, WITH THEIR NAME
AND SALARY AND SORTED ALPHABETICALLY BY NAME
FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES
db.departments.aggregate(
[
{$match: { "DEPTNO": {$ne:10}}}
, {$unwind: {path:"$emps"}}
, {$project: {
"ENAME": "$emps.ENAME",
"SAL": "$emps.SAL",
"DEPTNO": 1,
}
}
, {$sort : {"ENAME":1}}
]
)
select staff.ename
, staff.sal
, d.deptno
from departments d
, table(d.staff) staff
where d.deptno != 10
order
by staff.ename
TOTAL SALARY SUM, TOTAL NUMBER OF EMPLOYEES, THE HIGHEST SALARY
AND THE EARLIEST STARTDATE, PER DEPARTMENT
FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES
db.departments.aggregate(
[
{$unwind: {path:"$emps"}}
, {$group:{ _id: '$deptno'
, total_salary_sum : {$sum: "$emps.SAL"}
, total_staff_count : {$sum: 1}
, max_sal : {$max: "$emps.SAL"}
, min_startdate : {$min: "$emps.startdate"}
}
}
]
)
select d.deptno
, sum(staff.sal) total_salary_sum
, count(staff.empno) total_staff_count
, max(staff.sal) max_sal
, min(staff.startdate) min_startdate
from departments d
, table(d.staff) staff
group
by d.deptno
ADDING GEO LOCATIONS AND CREATE GEO INDEX
db.dept.findAndModify({
query: { loc: "NEW YORK" },
update: { $set: { "location" : {
"type" : "Point",
"coordinates" : [ -73.9352, 40.7306 ]
}
} },
upsert: true
})
db.dept.findAndModify({
query: { loc: "DALLAS" },
update: { $set: { "location" : {
"type" : "Point",
"coordinates" : [ -96.8005, 32.7801 ]
}
} },
upsert: true
})
db.dept.findAndModify({
query: { loc: "BOSTON" },
update: { $set: { "location" : {
"type" : "Point",
"coordinates" : [ -71.0598, 42.3584 ]
}
} },
upsert: true
})
...
-- create spatial index
db.dept.ensureIndex( { location : "2dsphere" } );
-- add column geo_location to hold SDO_GEOMETRY
alter table dept
add (geo_location SDO_GEOMETRY)
-- add geo location to each department
update dept
set geo_location = SDO_GEOMETRY(2001, 8307,
SDO_POINT_TYPE (-73.935242, 40.730610,NULL)
, NULL, NULL)
where loc = 'NEW YORK'
update dept
set geo_location = SDO_GEOMETRY(2001, 8307,
SDO_POINT_TYPE (-96.8005, 32.7801,NULL), NULL, NULL)
where loc = 'DALLAS'
-- insert dimensional meta information for the spatial column
INSERT INTO USER_SDO_GEOM_METADATA
(TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)
VALUES ('DEPT', 'GEO_LOCATION',
SDO_DIM_ARRAY
(SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5),
SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)
),
8307
);
-- create spatial index
CREATE INDEX dept_spatial_idx
ON dept(geo_location)
INDEXTYPE IS mdsys.spatial_index;
FIND DEPARTMENTS WITHIN 500 KM FROM WASHINGTON DC
( [ -77.0364, 38.8951 ])
db.dept.find(
{
location : {
$near : {
$geometry : {
type : "Point" ,
coordinates : [ -77.0364, 38.8951 ]
},
$maxDistance : 500000
}
}
}
)
with d as
( SELECT loc
, SDO_GEOM.SDO_DISTANCE
( SDO_GEOMETRY(2001, 8307
, SDO_POINT_TYPE ( -77.0364, 38.8951,NULL)
, NULL, NULL
)
, geo_location
, 0.005
, 'unit=KM'
) distance
from dept
)
select d.*
from d
where d.distance < 500
ALL DEPARTMENTS, THE DISTANCE FOR EACH DEPARTMENT IN KILOMETER
FROM WASHINGTON DC, ORDERED BY THAT DISTANCE
db.dept.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -77.0364, 38.8951 ]
},
"spherical": true,
"distanceField": "distanceFromTarget",
"distanceMultiplier": 0.001 // from meter to km
}}
, {$sort : {"distanceFromTarget":1}}
, {$project: {
_id: 0,
dname: 1,
loc: 1,
"distance from Washington DC":
{ $trunc : "$distanceFromTarget"},
}
}
])
with d as
( SELECT loc
, dname
, SDO_GEOM.SDO_DISTANCE
( SDO_GEOMETRY(2001, 8307
, SDO_POINT_TYPE ( -77.0364, 38.8951,NULL)
, NULL, NULL
)
, geo_location
, 0.005
, 'unit=KM'
) distance
from dept
)
select d.dname
, d.loc
, d.distance “distance from Washington DC”
from d
order
by d.distance
ADD BIOGRAPHIES TO EMPLOYEES (PREPARING FOR TEXT INDEX AND
SEARCH) AND CREATE TEXT INDEX
db.emp.findAndModify({
query: { ENAME: "KING" },
update: { $set: { "bio" : "Gerald Ford was born ...." }
},
upsert: true
})
db.emp.findAndModify({
query: { ENAME: "BLAKE" },
update: { $set: { "bio" : "Jamaican sprinter Yohan Blake
..." }
},
upsert: true
})
db.emp.findAndModify({
query: { ENAME: "FORD" },
update: { $set: { "bio" : "Harrison Ford is one of
...Han Solo." }
},
upsert: true
})
-- create text index, allowing use of text search
db.emp.createIndex(
{ ENAME:'text',
JOB:'text',
BIO:'text',
}
,{ weights: { ENAME:10, JOB:5, bio:1}
, name: 'employee_text_index'
}
)
update emp
set bio = q'[Gerald Ford was born ... in 2006.]'
where ename = 'KING‘
update emp
set bio = q'[Jamaican sprinter Yohan Blake holds
...]'
where ename = 'BLAKE'
-- create a multi column text index
exec ctx_ddl.create_preference
( 'my_mcds', 'multi_column_datastore' )
exec ctx_ddl.set_attribute
( 'my_mcds', 'columns', 'bio, ename, job' )
-- to support stemming
exec ctxsys.ctx_ddl.create_preference
('my_lexer','BASIC_LEXER');
exec ctxsys.ctx_ddl.set_attribute
('my_lexer','index_stems','1');
exec ctxsys.ctx_ddl.create_preference
('my_wordlist','BASIC_WORDLIST');
exec ctxsys.ctx_ddl.set_attribute
('my_wordlist','stemmer','ENGLISH');
create index emp_txt_idx on emp( ename )
indextype is ctxsys.context
parameters( 'datastore my_mcds WORDLIST my_wordlist
LEXER my_lexer' )
WHICH EMPLOYEES ARE FOUND WHEN LOOKING FOR SOMEONE TO LEAD?
db.emp.find(
{$text: {$search: 'lead'}}
,{ENAME:1}
)
-- leveraging the multicolumn text index
-- on ename, bio and job
SELECT ename
, SCORE(1)
FROM emp
WHERE CONTAINS(ename, 'lead', 1) > 0
TEXT SEARCH INCLUDING SCORING - APPLYING WEIGHT AND DERIVING
APPLICABILITY
db.emp.aggregate(
[{ $match: { $text: { $search: 'managing' } } }
,{ $project: {
_id:0,
ENAME: 1,
score: { $meta: 'textScore' } }
}
,{ $sort: {score:-1} }
]
)
-- leveraging stemming and the multicolumn text index
-- on ename, bio and job
SELECT ename
, SCORE(1) score
FROM emp
WHERE CONTAINS(ename, '$manage', 1) > 0
order
By score desc

More Related Content

What's hot (20)

PPTX
File organization (part 1)
Dr. SURBHI SAROHA
 
PPT
Linkedlists
Rajendran
 
PPT
Normalization
ochesing
 
PDF
SQL Complete Tutorial. All Topics Covered
Danish Mehraj
 
PPT
How Cascading Style Sheets (CSS) Works
Amit Tyagi
 
PPTX
ABAP 7.x New Features and Commands
Dr. Kerem Koseoglu
 
PPTX
Linked list
FURQAN M LODHI
 
PPTX
University Database Management Project
Kavi
 
PDF
Indexing and Performance Tuning
MongoDB
 
PPT
Using subqueries to solve queries
Syed Zaid Irshad
 
PPTX
Aggregate Function - Database
Shahadat153031
 
PPT
Managing objects with data dictionary views
Syed Zaid Irshad
 
PPT
Using the set operators
Syed Zaid Irshad
 
PPT
Cascading Style Sheets(CSS)
Reshmi Rajan
 
PPTX
File Structures(Part 2)
Dr. SURBHI SAROHA
 
PDF
Introduction To Apache Lucene
Mindfire Solutions
 
PPTX
fundamentals of XML
hamsa nandhini
 
PPTX
joins and subqueries in big data analysis
SanSan149
 
PDF
AD3251-Data Structures Design-Notes-Searching-Hashing.pdf
Ramco Institute of Technology, Rajapalayam, Tamilnadu, India
 
PPT
Views, Triggers, Functions, Stored Procedures, Indexing and Joins
baabtra.com - No. 1 supplier of quality freshers
 
File organization (part 1)
Dr. SURBHI SAROHA
 
Linkedlists
Rajendran
 
Normalization
ochesing
 
SQL Complete Tutorial. All Topics Covered
Danish Mehraj
 
How Cascading Style Sheets (CSS) Works
Amit Tyagi
 
ABAP 7.x New Features and Commands
Dr. Kerem Koseoglu
 
Linked list
FURQAN M LODHI
 
University Database Management Project
Kavi
 
Indexing and Performance Tuning
MongoDB
 
Using subqueries to solve queries
Syed Zaid Irshad
 
Aggregate Function - Database
Shahadat153031
 
Managing objects with data dictionary views
Syed Zaid Irshad
 
Using the set operators
Syed Zaid Irshad
 
Cascading Style Sheets(CSS)
Reshmi Rajan
 
File Structures(Part 2)
Dr. SURBHI SAROHA
 
Introduction To Apache Lucene
Mindfire Solutions
 
fundamentals of XML
hamsa nandhini
 
joins and subqueries in big data analysis
SanSan149
 
AD3251-Data Structures Design-Notes-Searching-Hashing.pdf
Ramco Institute of Technology, Rajapalayam, Tamilnadu, India
 
Views, Triggers, Functions, Stored Procedures, Indexing and Joins
baabtra.com - No. 1 supplier of quality freshers
 

Viewers also liked (13)

PDF
MySQL Community and Commercial Edition
Mario Beck
 
PPTX
Getting Campus-Wide Adoption - Happy Faculty - via Blackboard Collaborate
Mike Shaffer
 
PPTX
Embedding Library Services in Blackboard Learn
BlackboardEMEA
 
PDF
Incorporating ResearchReady into Blackboard Learn Using LTI Integration
Imagine Easy Solutions
 
PPT
Blackboard
zeniaaa
 
PPTX
Difference Between Sql - MySql and Oracle
Steve Johnson
 
PDF
Mysql vs oracle Kecepatan Transaksi, Index, dan Resource doc
Ananda Dwi Satrio
 
PPTX
Oracle mysql comparison
Arun Sharma
 
PDF
Blackboard Learn integration overview: 9.1, SaaS, and Ultra - Scott Hurrey, M...
Blackboard APAC
 
PPTX
Supporting Blackboard today and tomorrow with integrated solutions, Pearson E...
Blackboard APAC
 
PPTX
Integrating Blackboard Collaborate 12 and Moodle
NetSpot Pty Ltd
 
PDF
Mysql vs oracle Kecepatan Transaksi, Index, dan Resource
Ananda Dwi Satrio
 
PPTX
Integrating the Student Information System and Blackboard - you just press a ...
Blackboard APAC
 
MySQL Community and Commercial Edition
Mario Beck
 
Getting Campus-Wide Adoption - Happy Faculty - via Blackboard Collaborate
Mike Shaffer
 
Embedding Library Services in Blackboard Learn
BlackboardEMEA
 
Incorporating ResearchReady into Blackboard Learn Using LTI Integration
Imagine Easy Solutions
 
Blackboard
zeniaaa
 
Difference Between Sql - MySql and Oracle
Steve Johnson
 
Mysql vs oracle Kecepatan Transaksi, Index, dan Resource doc
Ananda Dwi Satrio
 
Oracle mysql comparison
Arun Sharma
 
Blackboard Learn integration overview: 9.1, SaaS, and Ultra - Scott Hurrey, M...
Blackboard APAC
 
Supporting Blackboard today and tomorrow with integrated solutions, Pearson E...
Blackboard APAC
 
Integrating Blackboard Collaborate 12 and Moodle
NetSpot Pty Ltd
 
Mysql vs oracle Kecepatan Transaksi, Index, dan Resource
Ananda Dwi Satrio
 
Integrating the Student Information System and Blackboard - you just press a ...
Blackboard APAC
 
Ad

Similar to Comparing 30 MongoDB operations with Oracle SQL statements (20)

PPTX
Comparing 30 Elastic Search operations with Oracle SQL statements
Lucas Jellema
 
DOCX
Sql Queries
User1test
 
PPTX
Analytic SQL Sep 2013
Connor McDonald
 
PPTX
Lecture 8 DML3 aggregate functions in DB.pptx
imranahmadrana28
 
PPTX
DBMS: Week 07 - Advanced SQL Queries in MySQL
RashidFaridChishti
 
PDF
Elasticsearch for Data Engineers
Duy Do
 
PDF
ILOUG 2019 - SQL features for Developers
Connor McDonald
 
PPTX
SQL.pptx
MrHello6
 
PDF
KScope19 - SQL Features
Connor McDonald
 
PDF
SQL-AGG-FUN.pdfiiiijuyyttfffgyyuyyyyyhhh
NaveeN547338
 
PPT
Aggregate Functions,Final
mukesh24pandey
 
PPTX
Data Retrival
Er. Nawaraj Bhandari
 
PDF
The Features That (maybe) You Didn't Know About
Oren Nakdimon
 
DOCX
Database Query Using SQL_ip.docx
VandanaGoyal21
 
PDF
Sangam 19 - Analytic SQL
Connor McDonald
 
PPTX
Data Base Management Slides SQL with example
AmeerHamza708060
 
PDF
SQL Top 10 Interview QnA By Rishabh Mishra in Hindi.pdf
SudhanshuPandey222889
 
DOC
Sql task answers
Nawaz Sk
 
DOCX
Complex queries in sql
Charan Reddy
 
PDF
6. Aggregate Functions.pdf
Sunita Milind Dol
 
Comparing 30 Elastic Search operations with Oracle SQL statements
Lucas Jellema
 
Sql Queries
User1test
 
Analytic SQL Sep 2013
Connor McDonald
 
Lecture 8 DML3 aggregate functions in DB.pptx
imranahmadrana28
 
DBMS: Week 07 - Advanced SQL Queries in MySQL
RashidFaridChishti
 
Elasticsearch for Data Engineers
Duy Do
 
ILOUG 2019 - SQL features for Developers
Connor McDonald
 
SQL.pptx
MrHello6
 
KScope19 - SQL Features
Connor McDonald
 
SQL-AGG-FUN.pdfiiiijuyyttfffgyyuyyyyyhhh
NaveeN547338
 
Aggregate Functions,Final
mukesh24pandey
 
Data Retrival
Er. Nawaraj Bhandari
 
The Features That (maybe) You Didn't Know About
Oren Nakdimon
 
Database Query Using SQL_ip.docx
VandanaGoyal21
 
Sangam 19 - Analytic SQL
Connor McDonald
 
Data Base Management Slides SQL with example
AmeerHamza708060
 
SQL Top 10 Interview QnA By Rishabh Mishra in Hindi.pdf
SudhanshuPandey222889
 
Sql task answers
Nawaz Sk
 
Complex queries in sql
Charan Reddy
 
6. Aggregate Functions.pdf
Sunita Milind Dol
 
Ad

More from Lucas Jellema (20)

PPTX
Introduction to web application development with Vue (for absolute beginners)...
Lucas Jellema
 
PPTX
Making the Shift Left - Bringing Ops to Dev before bringing applications to p...
Lucas Jellema
 
PPTX
Lightweight coding in powerful Cloud Development Environments (DigitalXchange...
Lucas Jellema
 
PPTX
Apache Superset - open source data exploration and visualization (Conclusion ...
Lucas Jellema
 
PPTX
CONNECTING THE REAL WORLD TO ENTERPRISE IT – HOW IoT DRIVES OUR ENERGY TRANSI...
Lucas Jellema
 
PPTX
Help me move away from Oracle - or not?! (Oracle Community Tour EMEA - LVOUG...
Lucas Jellema
 
PPTX
Op je vingers tellen... tot 1000!
Lucas Jellema
 
PPTX
IoT - from prototype to enterprise platform (DigitalXchange 2022)
Lucas Jellema
 
PPTX
Who Wants to Become an IT Architect-A Look at the Bigger Picture - DigitalXch...
Lucas Jellema
 
PPTX
Steampipe - use SQL to retrieve data from cloud, platforms and files (Code Ca...
Lucas Jellema
 
PPTX
Automation of Software Engineering with OCI DevOps Build and Deployment Pipel...
Lucas Jellema
 
PPTX
Introducing Dapr.io - the open source personal assistant to microservices and...
Lucas Jellema
 
PPTX
How and Why you can and should Participate in Open Source Projects (AMIS, Sof...
Lucas Jellema
 
PPTX
Microservices, Apache Kafka, Node, Dapr and more - Part Two (Fontys Hogeschoo...
Lucas Jellema
 
PPTX
Microservices, Node, Dapr and more - Part One (Fontys Hogeschool, Spring 2022)
Lucas Jellema
 
PPTX
6Reinventing Oracle Systems in a Cloudy World (RMOUG Trainingdays, February 2...
Lucas Jellema
 
PPTX
Help me move away from Oracle! (RMOUG Training Days 2022, February 2022)
Lucas Jellema
 
PPTX
Tech Talks 101 - DevOps (jan 2022)
Lucas Jellema
 
PPTX
Conclusion Code Cafe - Microcks for Mocking and Testing Async APIs (January 2...
Lucas Jellema
 
PPTX
Cloud Native Application Development - build fast, low TCO, scalable & agile ...
Lucas Jellema
 
Introduction to web application development with Vue (for absolute beginners)...
Lucas Jellema
 
Making the Shift Left - Bringing Ops to Dev before bringing applications to p...
Lucas Jellema
 
Lightweight coding in powerful Cloud Development Environments (DigitalXchange...
Lucas Jellema
 
Apache Superset - open source data exploration and visualization (Conclusion ...
Lucas Jellema
 
CONNECTING THE REAL WORLD TO ENTERPRISE IT – HOW IoT DRIVES OUR ENERGY TRANSI...
Lucas Jellema
 
Help me move away from Oracle - or not?! (Oracle Community Tour EMEA - LVOUG...
Lucas Jellema
 
Op je vingers tellen... tot 1000!
Lucas Jellema
 
IoT - from prototype to enterprise platform (DigitalXchange 2022)
Lucas Jellema
 
Who Wants to Become an IT Architect-A Look at the Bigger Picture - DigitalXch...
Lucas Jellema
 
Steampipe - use SQL to retrieve data from cloud, platforms and files (Code Ca...
Lucas Jellema
 
Automation of Software Engineering with OCI DevOps Build and Deployment Pipel...
Lucas Jellema
 
Introducing Dapr.io - the open source personal assistant to microservices and...
Lucas Jellema
 
How and Why you can and should Participate in Open Source Projects (AMIS, Sof...
Lucas Jellema
 
Microservices, Apache Kafka, Node, Dapr and more - Part Two (Fontys Hogeschoo...
Lucas Jellema
 
Microservices, Node, Dapr and more - Part One (Fontys Hogeschool, Spring 2022)
Lucas Jellema
 
6Reinventing Oracle Systems in a Cloudy World (RMOUG Trainingdays, February 2...
Lucas Jellema
 
Help me move away from Oracle! (RMOUG Training Days 2022, February 2022)
Lucas Jellema
 
Tech Talks 101 - DevOps (jan 2022)
Lucas Jellema
 
Conclusion Code Cafe - Microcks for Mocking and Testing Async APIs (January 2...
Lucas Jellema
 
Cloud Native Application Development - build fast, low TCO, scalable & agile ...
Lucas Jellema
 

Recently uploaded (20)

PPTX
Comprehensive Guide: Shoviv Exchange to Office 365 Migration Tool 2025
Shoviv Software
 
PPTX
Revolutionizing Code Modernization with AI
KrzysztofKkol1
 
PDF
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
PDF
Streamline Contractor Lifecycle- TECH EHS Solution
TECH EHS Solution
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PPTX
Fundamentals_of_Microservices_Architecture.pptx
MuhammadUzair504018
 
PPTX
Tally software_Introduction_Presentation
AditiBansal54083
 
DOCX
Import Data Form Excel to Tally Services
Tally xperts
 
PPTX
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
PPT
MergeSortfbsjbjsfk sdfik k
RafishaikIT02044
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PPTX
MiniTool Power Data Recovery Full Crack Latest 2025
muhammadgurbazkhan
 
PDF
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
PPTX
Equipment Management Software BIS Safety UK.pptx
BIS Safety Software
 
PPTX
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
PDF
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
PPTX
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
PPTX
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
PPTX
3uTools Full Crack Free Version Download [Latest] 2025
muhammadgurbazkhan
 
PPTX
How Apagen Empowered an EPC Company with Engineering ERP Software
SatishKumar2651
 
Comprehensive Guide: Shoviv Exchange to Office 365 Migration Tool 2025
Shoviv Software
 
Revolutionizing Code Modernization with AI
KrzysztofKkol1
 
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
Streamline Contractor Lifecycle- TECH EHS Solution
TECH EHS Solution
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
Fundamentals_of_Microservices_Architecture.pptx
MuhammadUzair504018
 
Tally software_Introduction_Presentation
AditiBansal54083
 
Import Data Form Excel to Tally Services
Tally xperts
 
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
MergeSortfbsjbjsfk sdfik k
RafishaikIT02044
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
MiniTool Power Data Recovery Full Crack Latest 2025
muhammadgurbazkhan
 
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
Equipment Management Software BIS Safety UK.pptx
BIS Safety Software
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
3uTools Full Crack Free Version Download [Latest] 2025
muhammadgurbazkhan
 
How Apagen Empowered an EPC Company with Engineering ERP Software
SatishKumar2651
 

Comparing 30 MongoDB operations with Oracle SQL statements

  • 1. COMPARING MONGODB SEARCH WITH RACLE SQL QUERIES MongoDB Find & Aggregate vs comparable Oracle SQL queries Lucas Jellema O
  • 2. TOPICS • Filter & Sort (find, sort) • Aggregation ($group, $project, $match, $sort) • Lookup & Outer Join ($lookup, $arrayElemAt) • Facet Search ($facet, $bucket, $sortByCount) • Update (findAndModify, forEach, save, update, upsert, $set, $unset) • Date and Time operations • Materialized View ($out) • Nested documents/tables ($unwind, $reduce) • Geospatial (ensureIndex, 2dsphere, $near, $geoNear) • Text Search (createIndex, text, $text, $search) • Stored Procedures (db.system.js.save, $where)
  • 3. DATA SET • HRM • Collections emp and dept – JSON documents in MongoDB database • Tables EMP and DEPT – relational records in Oracle Database
  • 4. HRM DATA SET JSON DOCUMENT COLLECTIONS EMP AND DEPT
  • 5. HRM DATA SET TABLES EMP AND DEPT
  • 6. ALL SOURCES ARE AVAILABLE ON GITHUB • https://github.com/lucasjellema/sig-nosql-mongodb
  • 7. FIND THE NAMES OF ALL MANAGERS db.emp.find ( {"JOB":"MANAGER"} , {ENAME:1} ) select ename from emp Where job = 'MANAGER'
  • 8. FIND NAME AND SALARY OF SALESMEN ORDERED BY SALARY FROM HIGH TO LOW db.emp.find ( {"JOB":"SALESMAN"} , { ENAME:1 , SAL:1} ) .sort ( {'SAL':-1}) select ename , sal from emp where job = 'SALESMAN' order by sal desc
  • 9. FIND NAME AND SALARY OF TWO HIGHEST EARNING SALESMEN – BEST PAID FIRST db.emp.find ( {"JOB":"SALESMAN"} , { ENAME:1 , SAL:1} ) .sort ( {'SAL':-1}) .limit(2) select ename , sal from emp where job = 'SALESMAN' order by sal desc FETCH FIRST 2 ROWS ONLY
  • 10. FIND EMPLOYEES WITH ‘AR’ IN THEIR NAME – IN ALPHABETICAL ORDER BY NAME db.emp.find ( {"ENAME":{$regex: "AR"} } , { ENAME:1 , SAL:1} ) .sort ( {'ENAME':1}) select ename , sal from emp where ename like '%AR%' order by ename
  • 11. FIND EMPLOYEES NOT IN DEPARTMENT 10, NAME AND SALARY AND SORTED ALPHABETICALLY BY NAME db.emp.find ( { "DEPTNO":{$ne: 10} } , { ENAME:1 , SAL:1 , DEPTNO:1 } ) .sort ( {'ENAME':1}) select ename , sal , deptno from emp where deptno != 10 order by ename
  • 12. SET DATE TYPE PROPERTY STARTDATE DERIVED FROM STRING TYPE PROPERTY HIREDATE db.emp.find().forEach ( function (elem) { elem.startdate = new Date( "19“ + elem.HIREDATE.substring(6) + "-" + elem.HIREDATE.substring(3,5) + "-" + elem.HIREDATE.substring(0,2) ); db.emp.save(elem); } ) alter table emp add (startdate date) update emp set startdate = to_date( hiredate, 'DD-MM-RR')
  • 13. FIND SALESMEN WITH A TOTAL INCOME HIGHER THAN 2000 -- use $where with embedded JavaScript db.emp.find ( {"JOB":"SALESMAN" , $where : " this.SAL + (this.COMM != null? this.COMM: 0) > 2000" } ) select * from emp where sal + nvl(comm, 0) > 2000
  • 14. CREATE STORED FUNCTION SALARY CAP TO RETURN MAX SALARY PER JOB; USE SALARY CAP TO FIND EMPLOYEES EARNING OVER THEIR CAP db.system.js.save({ "_id": "salaryCap", "value": function(job) { return job=='CLERK'?1000 :(job=='ANALYST'?3500 :(job=='SALESMAN'?2000 :(job=='MANAGER'?3000 :10000 ))); } }) -- load function in current database db.loadServerScripts(); db.emp.find( { $where : " this.SAL > salaryCap(this.JOB)"} , {ENAME:1, SAL:1, JOB:1}) create or replace function salary_cap (p_job in varchar2) return number is begin return case p_job when 'CLERK' then 1000 when 'ANALYST' then 3500 when 'SALESMAN' then 2000 when 'MANAGER' then 3000 else 10000 end; end salary_cap; select ename , sal , job from emp where sal > salary_cap( job)
  • 15. SELECT NAME, STARTMONTH AND STARTYEAR FOR ALL EMPLOYEES db.emp.aggregate( [{$project: { "ENAME": 1, "startmonth": { $month: "$startdate"}, "startyear": { $year: "$startdate"} } } ] ) select ename , extract (month from startdate) as startmonth , extract (year from startdate) as startyear from emp
  • 16. TOTAL SALARY SUM, TOTAL NUMBER OF EMPLOYEES, THE HIGHEST SALARY AND THE EARLIEST STARTDATE db.emp.aggregate( [{$group: { _id: null, total_salary_sum: { $sum: "$SAL" }, total_staff_count: { $sum: 1 }, max_sal: { $max: "$SAL" }, min_startdate: { $min: "$startdate" } } } ] ) select sum(sal) total_salary_sum , count(*) total_staff_count , max(sal) max_sal , min(startdate) min_startdate from emp
  • 17. TOTAL SALARY SUM, TOTAL NUMBER OF EMPLOYEES, THE HIGHEST SALARY AND THE EARLIEST STARTDATE PER DEPARTMENT db.emp.aggregate( [{$group: { _id: "$DEPTNO", total_salary_sum: { $sum: "$SAL" }, total_staff_count: { $sum: 1 }, max_sal: { $max: "$SAL" }, min_startdate: { $min: "$startdate" } } } ] ) select deptno , extract (year from startdate) hireyear , sum(sal) total_salary_sum , count(*) total_staff_count , max(sal) max_sal , min(startdate) min_startdate from emp group by deptno , extract (year from startdate)
  • 18. TOTAL SALARY SUM, NUMBER OF EMPLOYEES, HIGHEST SALARY AND EARLIEST STARTDATE PER DEPARTMENT AND HIREYEAR WITH NUMBER OF EMPLOYEES TWO OR MORE db.emp.aggregate( [{$group: { _id: { deptno: "$DEPTNO“ , hireyear : { $year: "$startdate"} }, total_salary_sum: { $sum: "$SAL" }, total_staff_count: { $sum: 1 }, max_sal: { $max: "$SAL" }, min_startdate: { $min: "$startdate" } } } ,{$match: { total_staff_count: { $gt: 1 } } } ] ) select deptno , extract (year from startdate) hireyear , sum(sal) total_salary_sum , count(*) total_staff_count , max(sal) max_sal , min(startdate) min_startdate from emp having count(*) > 1 group by deptno , extract (year from startdate)
  • 19. ALL EMPLOYEES WITH THEIR DEPARTMENT DETAILS (WHEN AVAILABLE) db.emp.aggregate( [{$lookup: { from:"dept", localField:"DEPTNO", foreignField:"deptno", as:"dept" } ,{$project: { "EMPNO": 1, "ENAME": 1, "DEPT": { $arrayElemAt:["$dept", 0]} } } ] ) select e.* , d.* from emp e left outer join dept d on (e.deptno = d.deptno)
  • 20. ALL DEPARTMENTS WITH A LIST OF THE NAMES OF THEIR EMPLOYEES db.dept.aggregate( [{$lookup: { from:"emp", localField:"deptno", foreignField:"DEPTNO", as:"emps" } } ,{$project: { "deptno": 1, "dname": 1, "staff": { $reduce: { input: "$emps", initialValue: "", in: { $concat : ["$$value" , ", " ,"$$this.ENAME"] } } // reduce } // staff } // project } ]) select d.deptno, d.dname , listagg( ename, ',') within group (order by ename) as "staff" from dept d left outer join emp e on (d.deptno = e.deptno) group by d.deptno , d.dname
  • 21. ALL EMPLOYEES WHO WORK IN NEW YORK db.emp.aggregate( [{$lookup: { from:"dept", localField:"DEPTNO", foreignField:"deptno", as:"dept" } ,{$project: { "EMPNO": 1, "ENAME": 1, "DEPT": { $arrayElemAt:["$dept", 0]} } } , {$match: { "DEPT.loc" :"NEW YORK"} } ] ) select e.* , d.* from emp e left outer join dept d on (e.deptno = d.deptno) where d.loc = 'NEW YORK'
  • 22. EMPLOYEE NAMED KING WITH ALL EMPLOYEES WHO WORK UNDER HER OR HIM AND A NEAT LIST OF THE NAMES OF THESE SUBORDINATE STAFF db.emp.aggregate( [{$match: { ENAME: "KING"}} ,{$lookup: { from:"emp", localField:"EMPNO", foreignField:"MGR", as:"subordinates" } } ,{$project: { "EMPNO": 1, "ENAME": 1, "subordinates": 1, "staff": { $reduce: { input: "$subordinates", initialValue: "", in: { $concat : ["$$value", ", ","$$this.ENAME"] } //in } // reduce }, } } ] ) select e.* , cursor( select * from emp s where s.mgr = e.empno ) subordinates , ( select listagg( s.ename, ',') within group (order by ename) from emp s where s.mgr = e.empno ) as "staff" from emp e where e.ename = 'KING'
  • 23. FACET AGGREGATION: # EMPLOYEES BY JOB, BY SALARY BUCKET, BY DEPARTMENT AND BY STARTDATE (1) db.emp.aggregate( [{$facet: { "categorizedByJob": [ { $sortByCount: "$JOB" } ], "categorizedBySalary": [ {$bucket: { groupBy: "$SAL", boundaries: [0, 1000, 2000 ,3000 ,10000 ], default: "Other", output: { "count": { $sum: 1 }, "employees": { $push: "$ENAME" } } // output }// bucket } ], "categorizedByDepartment": [ { $sortByCount: "$DEPTNO" } ], "categorizedByHiredate(Auto)": [ { $bucketAuto: { groupBy: "$startdate", buckets: 4 } } ] } } ]) -- categorizedByJob select job , count(*) as "count" from emp group by job order by "count" desc -- categorizedByDepartment select deptno , count(*) as "count" from emp group by deptno order by "count" desc
  • 24. FACET AGGREGATION: # EMPLOYEES BY JOB, BY SALARY BUCKET, BY DEPARTMENT AND BY STARTDATE (2) db.emp.aggregate( [{$facet: { "categorizedByJob": [ { $sortByCount: "$JOB" } ], "categorizedBySalary": [ {$bucket: { groupBy: "$SAL", boundaries: [0, 1000, 2000 ,3000 ,10000 ], default: "Other", output: { "count": { $sum: 1 }, "employees": { $push: "$ENAME" } } // output }// bucket } ], "categorizedByDepartment": [ { $sortByCount: "$DEPTNO" } ], "categorizedByHiredate(Auto)": [ { $bucketAuto: { groupBy: "$startdate", buckets: 4 } } ] } } ]) -- categorizedBySalary with bucket_boundaries as ( select 10000 lower_boundary from dual union all select 2000 lower_boundary from dual union all select 3000 lower_boundary from dual union all select 10000 lower_boundary from dual ) , buckets as ( select lower_boundary , lead(lower_boundary) over (order by lower_boundary)-1 upper_boundary from bucket_boundaries ) select lower_boundary , count(*) from emp left outer join buckets on (sal between lower_boundary and upper_boundary) group by lower_boundary
  • 25. FACET AGGREGATION: # EMPLOYEES BY JOB, BY SALARY BUCKET, BY DEPARTMENT AND BY STARTDATE (3) db.emp.aggregate( [{$facet: { "categorizedByJob": [ { $sortByCount: "$JOB" } ], "categorizedBySalary": [ {$bucket: { groupBy: "$SAL", boundaries: [0, 1000, 2000 ,3000 ,10000 ], default: "Other", output: { "count": { $sum: 1 }, "employees": { $push: "$ENAME" } } // output }// bucket } ], "categorizedByDepartment": [ { $sortByCount: "$DEPTNO" } ], "categorizedByHiredate(Auto)": [ { $bucketAuto: { groupBy: "$startdate", buckets: 4 } } ] } } ]) -- categorizedByHiredate with tiled as ( select ename , startdate , ntile(4) over (order by startdate asc) as size_bucket from emp ) select size_bucket , count(*) as "count" , listagg( ename, ',') within group (order by startdate) employees from tiled group by size_bucket order by size_bucket
  • 26. CREATE MATERIALIZED COLLECTION FROM QUERY DEPARTMENTS WITH NESTED EMPLOYEES db.dept.aggregate( [ {$lookup: { from:"emp", localField:"deptno", foreignField:"DEPTNO", as:"emps" } } , {$out: "departments" } ] ) create or replace type emp_t as object ( EMPNO NUMBER(4) , ENAME VARCHAR2(10) , JOB VARCHAR2(9) , MGR NUMBER(4) , SAL NUMBER(7,2) , COMM NUMBER(7,2) , STARTDATE DATE ) create or replace type emp_tbl_t as table of emp_t -- create materialized view -- with nested table create materialized view departments BUILD IMMEDIATE REFRESH FORCE ON DEMAND as select deptno , dname , loc , cast ( multiset ( select empno, ename, job , mgr, sal, comm, hiredate from emp e where e.deptno = d.deptno ) as emp_tbl_t) staff from dept d
  • 27. FIND DEPARTMENT THAT CONTAINS EMPLOYEE NAMED KING FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES db.departments.find ( {"emps.ENAME":"KING"} ) select d.deptno , d.dname , d.loc from departments d where ( select count(*) from table(d.staff) where ename ='KING' ) > 0
  • 28. ONLY FIND EMPLOYEE KING (AND NOT ALL EMPLOYEES IN THE DEPARTMENT) FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES db.departments.aggregate( [ {$unwind: {path:"$emps"}} , {$match: { "emps.ENAME": "KING"}} , {$project: { "EMPNO": "$emps.EMPNO", "JOB": "$emps.JOB", "ENAME": "$emps.ENAME", "STARTDATE": "$emps.startdate", "DNAME": 1 } } ] ) select d.deptno , d.dname , d.loc , staff.* from departments d , table(d.staff) staff where staff.ename = 'KING'
  • 29. FIND NAMES OF ALL MANAGERS FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES db.departments.aggregate( [ {$unwind: {path:"$emps"}} , {$match: { "emps.JOB": "MANAGER"}} , {$project: { "ENAME": "$emps.ENAME", } } ] ) select staff.ename from departments d , table(d.staff) staff where staff.job = 'MANAGER'
  • 30. FIND ALL EMPLOYEES WHO ARE NOT IN DEPARTMENT 10, WITH THEIR NAME AND SALARY AND SORTED ALPHABETICALLY BY NAME FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES db.departments.aggregate( [ {$match: { "DEPTNO": {$ne:10}}} , {$unwind: {path:"$emps"}} , {$project: { "ENAME": "$emps.ENAME", "SAL": "$emps.SAL", "DEPTNO": 1, } } , {$sort : {"ENAME":1}} ] ) select staff.ename , staff.sal , d.deptno from departments d , table(d.staff) staff where d.deptno != 10 order by staff.ename
  • 31. TOTAL SALARY SUM, TOTAL NUMBER OF EMPLOYEES, THE HIGHEST SALARY AND THE EARLIEST STARTDATE, PER DEPARTMENT FROM DEPARTMENTS COLLECTION WITH NESTED EMPLOYEES db.departments.aggregate( [ {$unwind: {path:"$emps"}} , {$group:{ _id: '$deptno' , total_salary_sum : {$sum: "$emps.SAL"} , total_staff_count : {$sum: 1} , max_sal : {$max: "$emps.SAL"} , min_startdate : {$min: "$emps.startdate"} } } ] ) select d.deptno , sum(staff.sal) total_salary_sum , count(staff.empno) total_staff_count , max(staff.sal) max_sal , min(staff.startdate) min_startdate from departments d , table(d.staff) staff group by d.deptno
  • 32. ADDING GEO LOCATIONS AND CREATE GEO INDEX db.dept.findAndModify({ query: { loc: "NEW YORK" }, update: { $set: { "location" : { "type" : "Point", "coordinates" : [ -73.9352, 40.7306 ] } } }, upsert: true }) db.dept.findAndModify({ query: { loc: "DALLAS" }, update: { $set: { "location" : { "type" : "Point", "coordinates" : [ -96.8005, 32.7801 ] } } }, upsert: true }) db.dept.findAndModify({ query: { loc: "BOSTON" }, update: { $set: { "location" : { "type" : "Point", "coordinates" : [ -71.0598, 42.3584 ] } } }, upsert: true }) ... -- create spatial index db.dept.ensureIndex( { location : "2dsphere" } ); -- add column geo_location to hold SDO_GEOMETRY alter table dept add (geo_location SDO_GEOMETRY) -- add geo location to each department update dept set geo_location = SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE (-73.935242, 40.730610,NULL) , NULL, NULL) where loc = 'NEW YORK' update dept set geo_location = SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE (-96.8005, 32.7801,NULL), NULL, NULL) where loc = 'DALLAS' -- insert dimensional meta information for the spatial column INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID) VALUES ('DEPT', 'GEO_LOCATION', SDO_DIM_ARRAY (SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5), SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5) ), 8307 ); -- create spatial index CREATE INDEX dept_spatial_idx ON dept(geo_location) INDEXTYPE IS mdsys.spatial_index;
  • 33. FIND DEPARTMENTS WITHIN 500 KM FROM WASHINGTON DC ( [ -77.0364, 38.8951 ]) db.dept.find( { location : { $near : { $geometry : { type : "Point" , coordinates : [ -77.0364, 38.8951 ] }, $maxDistance : 500000 } } } ) with d as ( SELECT loc , SDO_GEOM.SDO_DISTANCE ( SDO_GEOMETRY(2001, 8307 , SDO_POINT_TYPE ( -77.0364, 38.8951,NULL) , NULL, NULL ) , geo_location , 0.005 , 'unit=KM' ) distance from dept ) select d.* from d where d.distance < 500
  • 34. ALL DEPARTMENTS, THE DISTANCE FOR EACH DEPARTMENT IN KILOMETER FROM WASHINGTON DC, ORDERED BY THAT DISTANCE db.dept.aggregate([ { "$geoNear": { "near": { "type": "Point", "coordinates": [ -77.0364, 38.8951 ] }, "spherical": true, "distanceField": "distanceFromTarget", "distanceMultiplier": 0.001 // from meter to km }} , {$sort : {"distanceFromTarget":1}} , {$project: { _id: 0, dname: 1, loc: 1, "distance from Washington DC": { $trunc : "$distanceFromTarget"}, } } ]) with d as ( SELECT loc , dname , SDO_GEOM.SDO_DISTANCE ( SDO_GEOMETRY(2001, 8307 , SDO_POINT_TYPE ( -77.0364, 38.8951,NULL) , NULL, NULL ) , geo_location , 0.005 , 'unit=KM' ) distance from dept ) select d.dname , d.loc , d.distance “distance from Washington DC” from d order by d.distance
  • 35. ADD BIOGRAPHIES TO EMPLOYEES (PREPARING FOR TEXT INDEX AND SEARCH) AND CREATE TEXT INDEX db.emp.findAndModify({ query: { ENAME: "KING" }, update: { $set: { "bio" : "Gerald Ford was born ...." } }, upsert: true }) db.emp.findAndModify({ query: { ENAME: "BLAKE" }, update: { $set: { "bio" : "Jamaican sprinter Yohan Blake ..." } }, upsert: true }) db.emp.findAndModify({ query: { ENAME: "FORD" }, update: { $set: { "bio" : "Harrison Ford is one of ...Han Solo." } }, upsert: true }) -- create text index, allowing use of text search db.emp.createIndex( { ENAME:'text', JOB:'text', BIO:'text', } ,{ weights: { ENAME:10, JOB:5, bio:1} , name: 'employee_text_index' } ) update emp set bio = q'[Gerald Ford was born ... in 2006.]' where ename = 'KING‘ update emp set bio = q'[Jamaican sprinter Yohan Blake holds ...]' where ename = 'BLAKE' -- create a multi column text index exec ctx_ddl.create_preference ( 'my_mcds', 'multi_column_datastore' ) exec ctx_ddl.set_attribute ( 'my_mcds', 'columns', 'bio, ename, job' ) -- to support stemming exec ctxsys.ctx_ddl.create_preference ('my_lexer','BASIC_LEXER'); exec ctxsys.ctx_ddl.set_attribute ('my_lexer','index_stems','1'); exec ctxsys.ctx_ddl.create_preference ('my_wordlist','BASIC_WORDLIST'); exec ctxsys.ctx_ddl.set_attribute ('my_wordlist','stemmer','ENGLISH'); create index emp_txt_idx on emp( ename ) indextype is ctxsys.context parameters( 'datastore my_mcds WORDLIST my_wordlist LEXER my_lexer' )
  • 36. WHICH EMPLOYEES ARE FOUND WHEN LOOKING FOR SOMEONE TO LEAD? db.emp.find( {$text: {$search: 'lead'}} ,{ENAME:1} ) -- leveraging the multicolumn text index -- on ename, bio and job SELECT ename , SCORE(1) FROM emp WHERE CONTAINS(ename, 'lead', 1) > 0
  • 37. TEXT SEARCH INCLUDING SCORING - APPLYING WEIGHT AND DERIVING APPLICABILITY db.emp.aggregate( [{ $match: { $text: { $search: 'managing' } } } ,{ $project: { _id:0, ENAME: 1, score: { $meta: 'textScore' } } } ,{ $sort: {score:-1} } ] ) -- leveraging stemming and the multicolumn text index -- on ename, bio and job SELECT ename , SCORE(1) score FROM emp WHERE CONTAINS(ename, '$manage', 1) > 0 order By score desc