0
# SODA Operations
1
2
Simple Oracle Document Access (SODA) for JSON document storage and querying capabilities.
3
4
## Capabilities
5
6
### SODA Database
7
8
Get SODA database interface for document operations.
9
10
```javascript { .api }
11
/**
12
* Gets SODA database interface
13
* @returns SodaDatabase instance
14
*/
15
getSodaDatabase(): SodaDatabase;
16
17
interface SodaDatabase {
18
createCollection(name: string, options?: SodaCollectionOptions): Promise<SodaCollection>;
19
createDocument(content: any, options?: SodaDocumentOptions): SodaDocument;
20
getCollectionNames(options?: GetCollectionNamesOptions): Promise<string[]>;
21
openCollection(name: string): Promise<SodaCollection>;
22
}
23
24
interface SodaCollectionOptions {
25
metaData?: any;
26
mode?: number;
27
}
28
29
interface SodaDocumentOptions {
30
key?: string;
31
mediaType?: string;
32
}
33
34
interface GetCollectionNamesOptions {
35
startsWith?: string;
36
limit?: number;
37
}
38
```
39
40
**Usage Examples:**
41
42
```javascript
43
const oracledb = require('oracledb');
44
45
// Get SODA database
46
const soda = connection.getSodaDatabase();
47
48
// Create a collection
49
const collection = await soda.createCollection('products');
50
51
// List collections
52
const collectionNames = await soda.getCollectionNames();
53
console.log('Collections:', collectionNames);
54
55
// Open existing collection
56
const existingCollection = await soda.openCollection('products');
57
```
58
59
### SODA Collections
60
61
Manage JSON document collections with full CRUD operations.
62
63
```javascript { .api }
64
interface SodaCollection {
65
// Document operations
66
insertOne(document: SodaDocument | any): Promise<SodaWriteResult>;
67
insertOneAndGet(document: SodaDocument | any): Promise<SodaDocument>;
68
insertMany(documents: (SodaDocument | any)[]): Promise<SodaWriteResult>;
69
insertManyAndGet(documents: (SodaDocument | any)[]): Promise<SodaDocument[]>;
70
71
save(document: SodaDocument): Promise<SodaWriteResult>;
72
saveAndGet(document: SodaDocument): Promise<SodaDocument>;
73
74
// Query operations
75
find(): SodaOperation;
76
count(): Promise<number>;
77
78
// Collection management
79
drop(): Promise<boolean>;
80
truncate(): Promise<void>;
81
82
// Index management
83
createIndex(spec: any): Promise<void>;
84
dropIndex(name: string, options?: DropIndexOptions): Promise<boolean>;
85
listIndexes(): Promise<any[]>;
86
87
// Schema operations
88
getDataGuide(): Promise<SodaDocument>;
89
90
// Collection properties
91
metaData: any;
92
name: string;
93
}
94
95
interface SodaWriteResult {
96
inserted?: boolean;
97
replaced?: boolean;
98
}
99
100
interface DropIndexOptions {
101
force?: boolean;
102
}
103
```
104
105
**Usage Examples:**
106
107
```javascript
108
// Create and work with a collection
109
const collection = await soda.createCollection('employees');
110
111
// Insert a single document
112
const doc = {
113
name: 'John Doe',
114
department: 'Engineering',
115
salary: 75000,
116
skills: ['JavaScript', 'Oracle', 'Node.js']
117
};
118
119
const result = await collection.insertOne(doc);
120
console.log('Document inserted:', result.inserted);
121
122
// Insert and get the document back
123
const insertedDoc = await collection.insertOneAndGet(doc);
124
console.log('Document key:', insertedDoc.key);
125
console.log('Document content:', insertedDoc.getContent());
126
127
// Insert multiple documents
128
const employees = [
129
{ name: 'Alice Smith', department: 'Marketing', salary: 65000 },
130
{ name: 'Bob Johnson', department: 'Sales', salary: 70000 },
131
{ name: 'Carol Brown', department: 'Engineering', salary: 80000 }
132
];
133
134
const bulkResult = await collection.insertMany(employees);
135
console.log('Documents inserted:', bulkResult.inserted);
136
137
// Count documents
138
const count = await collection.count();
139
console.log('Total documents:', count);
140
141
// Get collection info
142
console.log('Collection name:', collection.name);
143
console.log('Collection metadata:', collection.metaData);
144
```
145
146
### SODA Documents
147
148
Work with individual JSON documents.
149
150
```javascript { .api }
151
interface SodaDocument {
152
// Document content
153
getContent(): any;
154
getContentAsBuffer(): Buffer;
155
getContentAsString(): string;
156
157
// Document metadata
158
key: string;
159
lastModified: string;
160
mediaType: string;
161
version: string;
162
163
// Document creation
164
createdOn: string;
165
}
166
167
class SodaDocument {
168
constructor();
169
getContent(): any;
170
getContentAsBuffer(): Buffer;
171
getContentAsString(): string;
172
key: string;
173
lastModified: string;
174
mediaType: string;
175
version: string;
176
createdOn: string;
177
}
178
```
179
180
**Usage Examples:**
181
182
```javascript
183
// Create document with specific key
184
const doc = soda.createDocument({
185
productId: 'PROD001',
186
name: 'Laptop',
187
price: 999.99
188
}, { key: 'PROD001' });
189
190
await collection.insertOne(doc);
191
192
// Retrieve and examine document
193
const operation = collection.find().key('PROD001');
194
const foundDoc = await operation.getOne();
195
196
if (foundDoc) {
197
console.log('Document key:', foundDoc.key);
198
console.log('Last modified:', foundDoc.lastModified);
199
console.log('Content:', foundDoc.getContent());
200
console.log('Content as string:', foundDoc.getContentAsString());
201
}
202
```
203
204
### SODA Queries
205
206
Advanced querying capabilities with fluent API.
207
208
```javascript { .api }
209
interface SodaOperation {
210
// Filtering
211
key(value: string): SodaOperation;
212
keys(values: string[]): SodaOperation;
213
filter(spec: any): SodaOperation;
214
215
// Pagination and ordering
216
skip(value: number): SodaOperation;
217
limit(value: number): SodaOperation;
218
219
// Execution
220
count(): Promise<number>;
221
getCursor(): Promise<SodaDocCursor>;
222
getDocuments(): Promise<SodaDocument[]>;
223
getOne(): Promise<SodaDocument>;
224
225
// Modification
226
remove(): Promise<SodaWriteResult>;
227
replaceOne(document: SodaDocument | any): Promise<SodaWriteResult>;
228
replaceOneAndGet(document: SodaDocument | any): Promise<SodaDocument>;
229
}
230
231
interface SodaDocCursor {
232
close(): Promise<void>;
233
getNext(): Promise<SodaDocument>;
234
}
235
```
236
237
**Usage Examples:**
238
239
```javascript
240
// Find documents by key
241
const doc = await collection.find().key('PROD001').getOne();
242
243
// Find multiple documents by keys
244
const docs = await collection.find().keys(['PROD001', 'PROD002']).getDocuments();
245
246
// Filter documents with JSON queries
247
const highSalaryEmployees = await collection
248
.find()
249
.filter({ salary: { $gt: 70000 } })
250
.getDocuments();
251
252
// Complex filtering
253
const engineeringDocs = await collection
254
.find()
255
.filter({
256
department: 'Engineering',
257
skills: { $in: ['JavaScript', 'Python'] }
258
})
259
.limit(10)
260
.getDocuments();
261
262
// Using cursor for large result sets
263
const cursor = await collection.find().getCursor();
264
let doc;
265
while ((doc = await cursor.getNext())) {
266
console.log('Processing document:', doc.key);
267
// Process document
268
}
269
await cursor.close();
270
271
// Count with filter
272
const count = await collection
273
.find()
274
.filter({ department: 'Engineering' })
275
.count();
276
277
console.log('Engineering employees:', count);
278
```
279
280
### Document Modification
281
282
Update and replace documents in collections.
283
284
```javascript { .api }
285
// Replace operations
286
replaceOne(document: SodaDocument | any): Promise<SodaWriteResult>;
287
replaceOneAndGet(document: SodaDocument | any): Promise<SodaDocument>;
288
289
// Remove operations
290
remove(): Promise<SodaWriteResult>;
291
292
// Save operations (upsert)
293
save(document: SodaDocument): Promise<SodaWriteResult>;
294
saveAndGet(document: SodaDocument): Promise<SodaDocument>;
295
```
296
297
**Usage Examples:**
298
299
```javascript
300
// Replace a document
301
const updatedEmployee = {
302
name: 'John Doe',
303
department: 'Engineering',
304
salary: 85000, // Increased salary
305
skills: ['JavaScript', 'Oracle', 'Node.js', 'React']
306
};
307
308
const replaceResult = await collection
309
.find()
310
.key('EMP001')
311
.replaceOne(updatedEmployee);
312
313
console.log('Document replaced:', replaceResult.replaced);
314
315
// Replace and get back the new document
316
const newDoc = await collection
317
.find()
318
.key('EMP001')
319
.replaceOneAndGet(updatedEmployee);
320
321
console.log('New version:', newDoc.version);
322
323
// Remove documents
324
const removeResult = await collection
325
.find()
326
.filter({ department: 'Discontinued' })
327
.remove();
328
329
console.log('Documents removed:', removeResult);
330
331
// Save (upsert) with specific key
332
const productDoc = soda.createDocument({
333
productId: 'PROD999',
334
name: 'New Product',
335
price: 199.99
336
}, { key: 'PROD999' });
337
338
const saveResult = await collection.save(productDoc);
339
console.log('Document saved:', saveResult.inserted || saveResult.replaced);
340
```
341
342
### Index Management
343
344
Create and manage indexes for optimal query performance.
345
346
```javascript { .api }
347
/**
348
* Creates an index on the collection
349
* @param spec - Index specification
350
* @returns Promise that resolves when index is created
351
*/
352
createIndex(spec: any): Promise<void>;
353
354
/**
355
* Drops an index from the collection
356
* @param name - Index name
357
* @param options - Optional drop options
358
* @returns Promise resolving to boolean indicating success
359
*/
360
dropIndex(name: string, options?: DropIndexOptions): Promise<boolean>;
361
362
/**
363
* Lists all indexes on the collection
364
* @returns Promise resolving to array of index specifications
365
*/
366
listIndexes(): Promise<any[]>;
367
```
368
369
**Usage Examples:**
370
371
```javascript
372
// Create a simple index
373
await collection.createIndex({
374
name: 'salaryIndex',
375
fields: [
376
{
377
path: 'salary',
378
datatype: 'number'
379
}
380
]
381
});
382
383
// Create a composite index
384
await collection.createIndex({
385
name: 'deptSalaryIndex',
386
fields: [
387
{
388
path: 'department',
389
datatype: 'string'
390
},
391
{
392
path: 'salary',
393
datatype: 'number'
394
}
395
]
396
});
397
398
// Create a functional index
399
await collection.createIndex({
400
name: 'upperNameIndex',
401
fields: [
402
{
403
path: 'name',
404
datatype: 'string',
405
order: 'asc'
406
}
407
]
408
});
409
410
// List all indexes
411
const indexes = await collection.listIndexes();
412
console.log('Collection indexes:', indexes);
413
414
// Drop an index
415
const dropped = await collection.dropIndex('salaryIndex');
416
console.log('Index dropped:', dropped);
417
```
418
419
### Collection Management
420
421
Advanced collection operations and configuration.
422
423
```javascript { .api }
424
/**
425
* Gets data guide for the collection
426
* @returns Promise resolving to SodaDocument containing schema information
427
*/
428
getDataGuide(): Promise<SodaDocument>;
429
430
/**
431
* Truncates the collection (removes all documents)
432
* @returns Promise that resolves when truncation is complete
433
*/
434
truncate(): Promise<void>;
435
436
/**
437
* Drops the collection
438
* @returns Promise resolving to boolean indicating success
439
*/
440
drop(): Promise<boolean>;
441
```
442
443
**Usage Examples:**
444
445
```javascript
446
// Get data guide (schema information)
447
const dataGuide = await collection.getDataGuide();
448
console.log('Collection schema:', dataGuide.getContent());
449
450
// Truncate collection (remove all documents)
451
await collection.truncate();
452
console.log('Collection truncated');
453
454
// Verify truncation
455
const count = await collection.count();
456
console.log('Document count after truncate:', count); // Should be 0
457
458
// Drop collection entirely
459
const dropped = await collection.drop();
460
console.log('Collection dropped:', dropped);
461
462
// Verify collection no longer exists
463
const collections = await soda.getCollectionNames();
464
console.log('Remaining collections:', collections);
465
```
466
467
### SODA Constants
468
469
```javascript { .api }
470
// Collection creation modes
471
const SODA_COLL_MAP_MODE = 1;
472
```
473
474
**Usage Examples:**
475
476
```javascript
477
// Create collection with specific mapping mode
478
const collection = await soda.createCollection('mappedCollection', {
479
mode: oracledb.SODA_COLL_MAP_MODE,
480
metaData: {
481
keyColumn: { name: 'ID' },
482
contentColumn: { name: 'JSON_DOCUMENT', jsonFormat: 'OSON' },
483
versionColumn: { name: 'VERSION' },
484
lastModifiedColumn: { name: 'LAST_MODIFIED' }
485
}
486
});
487
```