Skip to content

Commit a6fd048

Browse files
Merge pull request #1790 from oracle-devrel/witold-swierzy-patch-3
Witold swierzy patch 3
2 parents 887335f + cc435c7 commit a6fd048

36 files changed

+11306
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## NodeJS demos
2+
This directory contains NodeJS scripts using Oracle API for MongoDB and demonstrating its capabilities
3+
4+
## License
5+
6+
Copyright (c) 2025 Oracle and/or its affiliates.
7+
8+
Licensed under the Universal Permissive License (UPL), Version 1.0.
9+
10+
See [LICENSE](https://github.com/oracle-devrel/technology-engineering/blob/main/LICENSE) for more details.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
const {MongoClient} = require('mongodb');
2+
const fs = require('fs');
3+
4+
async function displayExecutionPlan(db,collection,statement,hint) {
5+
if (hint !== undefined)
6+
result = await db.collection(collection).find(statement).hint(hint).explain();
7+
else
8+
result = await db.collection(collection).find(statement).explain();
9+
console.log(result.queryPlanner);
10+
}
11+
12+
async function displaySQLExecutionPlan(db,sqlStatement) {
13+
result = db.aggregate([ {$sql: {statement: sqlStatement}}]).explain();
14+
console.log((await result).stages[0].$sql);
15+
}
16+
17+
async function getDBVersion(db) {
18+
let oracle_api = !(await isNativeMongoDB(db));
19+
20+
if (oracle_api) {
21+
result = db.aggregate([{ $sql: "select version_full from product_component_version" }] );
22+
return (await result.toArray())[0].VERSION_FULL;
23+
}
24+
else
25+
return (await db.admin().serverInfo()).version;
26+
}
27+
28+
async function isNativeMongoDB(db) {
29+
return !(await db.admin().serverInfo()).hasOwnProperty("oramlVersion");
30+
}
31+
32+
async function prepareSchema(db) {
33+
let data_set_dir = process.env.DATA_SET_DIR;
34+
let oracle_api = !(await isNativeMongoDB(db));
35+
36+
// EMPLOYEES relational table cleaning up
37+
if (oracle_api) {
38+
result = db.aggregate([{ $sql: "truncate table employees"}]);
39+
for await (res of result);
40+
result = db.aggregate([{ $sql: "truncate table departments"}]);
41+
for await (res of result);
42+
}
43+
44+
// DEPARTMENTS_COL and EMPLOYEES_COL preparation
45+
let departmentsArrayFile = data_set_dir + "/departments.json";
46+
let employeesArrayFile = data_set_dir + "/employees.json";
47+
let departments = JSON.parse(fs.readFileSync(departmentsArrayFile));
48+
let employees = JSON.parse(fs.readFileSync(employeesArrayFile));
49+
50+
// dropping views
51+
await db.dropCollection("DEPARTMENTS_COL_VW"); // view based on collection
52+
if (oracle_api) {
53+
await db.dropCollection("DEPARTMENTS_TAB_VW"); // JSON Collection view based on table
54+
await db.dropCollection("DEPARTMENTS_DUAL_VW"); // JSON Duality View based on table
55+
await db.dropCollection("EMPLOYEES_DUAL_VW"); // JSON Duality View based on table
56+
await db.dropCollection("DEPT_EMP_COL");
57+
}
58+
59+
// dropping collections
60+
await db.dropCollection("DEPARTMENTS_COL");
61+
await db.dropCollection("EMPLOYEES_COL");
62+
await db.dropCollection("DEPARTMENTS_COL_BKP");
63+
64+
// load data into DEPARTMENTS_COL collection
65+
await db.createCollection("DEPARTMENTS_COL");
66+
await db.collection("DEPARTMENTS_COL").insertMany(departments);
67+
// load data into EMPLOYEES_COL collection
68+
await db.createCollection("EMPLOYEES_COL");
69+
await db.collection("EMPLOYEES_COL").insertMany(employees);
70+
}
71+
72+
function sleep(ms) {
73+
return new Promise((resolve) => setTimeout(resolve, ms));
74+
}
75+
76+
module.exports = {displayExecutionPlan,displaySQLExecutionPlan,isNativeMongoDB,prepareSchema,getDBVersion,sleep};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const utils = require("./00_utils");
2+
const {MongoClient} = require("mongodb");
3+
4+
async function clear_db() {
5+
let client = new MongoClient(process.env.MONGO_URI);
6+
let db = client.db();
7+
let oracle_api = !(await utils.isNativeMongoDB(db));
8+
9+
let colls=[];
10+
let collName = "";
11+
let numColls = 0;
12+
13+
try {
14+
console.log("Cleaning up the database schema.");
15+
await utils.prepareSchema(db);
16+
console.log("Database schema is clear.");
17+
}
18+
catch (e) {
19+
console.error(e);
20+
}
21+
finally {
22+
await client.close();
23+
console.log("Disconnected from database.");
24+
}
25+
}
26+
27+
clear_db().catch(console.error);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
const utils = require("./00_utils");
2+
const {MongoClient} = require("mongodb");
3+
4+
async function basic_demo() {
5+
let client = new MongoClient(process.env.MONGO_URI);
6+
let db = client.db();
7+
let oracle_api = !(await utils.isNativeMongoDB(db));
8+
9+
let colls=[];
10+
let collName = "";
11+
let numColls = 0;
12+
13+
try {
14+
console.log("Preparing the database schema.");
15+
await utils.prepareSchema(db);
16+
console.log("Database schema prepared.");
17+
18+
if (oracle_api)
19+
console.log("You are connected to an Oracle MongoDB API service.");
20+
else
21+
console.log("You are connected to a native MongoDB database.");
22+
23+
// 1. list databases
24+
databasesList = await db.admin().listDatabases();
25+
console.log("Databases:");
26+
databasesList.databases.forEach(db => console.log(` ${db.name}`));
27+
28+
// 2. list collections in the default database
29+
colls = (await db.listCollections().toArray());
30+
console.log("Number of collections : "+colls.length);
31+
console.log("Collections : ");
32+
for ( i = 0; i < colls.length; i++ )
33+
console.log(" "+colls[i].name);
34+
35+
// 3. insert documents into DEPARTMENTS_COL collection
36+
console.log("Inserting department 120 - HR into DEPARTMENTS_COL collection");
37+
db.collection("DEPARTMENTS_COL").insertOne(
38+
{"_id" : 120, "department_name" : "Human Resources"}
39+
);
40+
console.log("Department 120, Human Resoures inserted.");
41+
42+
console.log("Inserting departments 130, 140 and 150 using insertMany method");
43+
db.collection("DEPARTMENTS_COL").insertMany([
44+
{"_id" : 130, "department_name" : "Department 130"},
45+
{"_id" : 140, "department_name" : "Department 140"},
46+
{"_id" : 150, "department_name" : "Department 150"}
47+
]);
48+
console.log("Departments 130, 140 and 150 inserted.");
49+
50+
// 4. reading data from DEPARTMENTS_COL collection
51+
console.log("Reading all documents from DEPARTMENTS_COL collection");
52+
depts = db.collection("DEPARTMENTS_COL").find().sort( {"_id" : 1} );
53+
for await (dept of depts)
54+
console.log("id : " + dept._id + " name : " + dept.department_name);
55+
56+
// 5. joining data from two collections
57+
console.log("Query joining DEPARTMENTS_COL and EMPLOYEES_COL collections");
58+
depts = db.collection("DEPARTMENTS_COL").aggregate
59+
([{
60+
$lookup : { from : "EMPLOYEES_COL",
61+
localField : "_id",
62+
foreignField : "department_id",
63+
as : "EMPLOYEEES" }
64+
}]);
65+
for await (dept of depts) {
66+
console.log(dept);
67+
}
68+
69+
// 6. create a backup collection and copying the data
70+
console.log("Creating DEPARTMENTS_COL_BKP collection.");
71+
await db.createCollection("DEPARTMENTS_COL_BKP");
72+
console.log("Collection DEPARTMENTS_COL_BKP created.");
73+
74+
console.log("Copying data from DEPARTMENTS_COL to DEPARTMENTS_COL_BKP.");
75+
depts = db.collection("DEPARTMENTS_COL").find().sort( {"_id" : 1} );
76+
for await (dept of depts) {
77+
await db.collection("DEPARTMENTS_COL_BKP").insertOne(dept);
78+
console.log("Department #"+dept._id+" copied to backup collection.")
79+
}
80+
console.log("Backup completed.");
81+
console.log("Number of copied documents : " + (await db.collection("DEPARTMENTS_COL_BKP").countDocuments()));
82+
}
83+
catch (e) {
84+
console.error(e);
85+
}
86+
finally {
87+
await client.close();
88+
console.log("Disconnected from database.");
89+
}
90+
}
91+
92+
basic_demo().catch(console.error);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const utils = require("./00_utils");
2+
const {MongoClient} = require("mongodb");
3+
4+
async function expr() {
5+
let client = new MongoClient(process.env.MONGO_URI);
6+
let db = client.db();
7+
let oracle_api = !(await utils.isNativeMongoDB(db));
8+
9+
try {
10+
console.log("Preparing the database schema.");
11+
await utils.prepareSchema(db);
12+
console.log("Database schema prepared.");
13+
14+
if (oracle_api)
15+
console.log("You are connected to an Oracle MongoDB API service.");
16+
else
17+
console.log("You are connected to a native MongoDB database.");
18+
19+
if (!oracle_api) {
20+
console.log("You are using native MongoDB service. $expr operator is fully supported.");
21+
emps = db.collection("EMPLOYEES_COL").find({$expr: {$lt: ["$manager_id","$_id"]}});
22+
}
23+
else {
24+
try {
25+
console.log("Query using $expr operator.");
26+
console.log("db.EMPLOYEES_COL.find({$expr: {$lt: ['$manager_id','$_id']}})")
27+
emps = db.collection("EMPLOYEES_COL").find({$expr: {$lt: ["$manager_id","$_id"]}});
28+
for await (emp of emps) {
29+
console.log(emp.last_name + " " + emp.first_name);
30+
}
31+
}
32+
catch (e) {
33+
console.log("You are using Oracle MongoDB API. $epr operator has limited support.");
34+
console.error(e);
35+
}
36+
console.log("You are using Oracle MongoDB API. There is need to use $sql operator instead of $expr.");
37+
console.log("Query : select c.DATA from EMPLOYEES_COL c where c.DATA.manager_id < c.DATA.'_id'");
38+
emps = db.aggregate([{ $sql: 'select c.DATA from EMPLOYEES_COL c where c.DATA.manager_id < c.DATA."_id"' }] );
39+
console.log("Execution plan : ");
40+
await utils.displaySQLExecutionPlan(db,'select c.DATA from EMPLOYEES_COL c where c.DATA.manager_id < c.DATA."_id"');
41+
}
42+
for await (emp of emps)
43+
console.log(emp.last_name + " " + emp.first_name);
44+
}
45+
catch (e) {
46+
console.error(e);
47+
}
48+
finally {
49+
await client.close();
50+
console.log("Disconnected from database.");
51+
}
52+
}
53+
54+
expr().catch(console.error);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
const utils = require("./00_utils");
2+
const {MongoClient} = require("mongodb");
3+
const fs = require('fs');
4+
5+
async function views() {
6+
let client = new MongoClient(process.env.MONGO_URI);
7+
let db = client.db();
8+
let oracle_api = !(await utils.isNativeMongoDB(db));
9+
let data_set_dir = process.env.DATA_SET_DIR;
10+
let departmentsArrayFile = data_set_dir + "/departments.json";
11+
let employeesArrayFile = data_set_dir + "/employees.json";
12+
13+
try {
14+
console.log("Preparing the database schema.");
15+
await utils.prepareSchema(db);
16+
console.log("Database schema prepared.");
17+
18+
console.log("Creating view DEPARTMENTS_COL_VW based on DEPARTMENTS_COL collection");
19+
await db.createCollection("DEPARTMENTS_COL_VW",{viewOn : "DEPARTMENTS_COL", pipeline : [] } );
20+
console.log("DEPARTMENTS_COL_VW read-only view created.");
21+
22+
23+
console.log("Checking the execution plan of a query using the view");
24+
console.log("Query : db.DEPARTMENTS_COL_VW.find({{ '_id' : {$lte : 80 }}})");
25+
depts = db.collection("DEPARTMENTS_COL_VW").find({ "_id" : {$lte : 80 }});
26+
for await (dept of depts)
27+
console.log(dept._id+" "+dept.department_name);
28+
await utils.displayExecutionPlan(db,"DEPARTMENTS_COL_VW",{ "_id" : {$lte : 80 }});
29+
try {
30+
console.log("Trying to update DEPARTMENTS_COL_VW");
31+
result = await db.collection("DEPARTMENTS_COL_VW").updateOne({_id:190},{$set:{department_name:"NoName"}});
32+
console.log("Number of modified rows : "+result.modifiedCount);
33+
if (oracle_api) {
34+
console.log("You are using Oracle MongoDB API.");
35+
console.log("Updates on collection views don't raise any exceptions, but are just ignored.");
36+
}
37+
}
38+
catch (e) {
39+
if (!oracle_api)
40+
console.log("You are connected to a native MongoDB instance. Updates on VIEWS raise exceptions.");
41+
console.error(e);
42+
}
43+
}
44+
catch (e) {
45+
console.error(e);
46+
}
47+
finally {
48+
await client.close();
49+
console.log("Disconnected from database.");
50+
}
51+
}
52+
53+
views().catch(console.error);

0 commit comments

Comments
 (0)