### find(cname, qobj, orarr, hints, cb)
Execute query on collection.
EJDB queries inspired by MongoDB (mongodb.org) and follows same philosophy.
Supported queries:
- Simple matching of String OR Number OR Array value:
- {'json.field.path' : 'val', ...}
- $not Negate operation.
- {'json.field.path' : {'$not' : val}} //Field not equal to val
- {'json.field.path' : {'$not' : {'$begin' : prefix}}} //Field not begins with val
- $begin String starts with prefix
- {'json.field.path' : {'$begin' : prefix}}
- $gt, $gte (>, >=) and $lt, $lte for number types:
- {'json.field.path' : {'$gt' : number}, ...}
- $bt Between for number types:
- {'json.field.path' : {'$bt' : [num1, num2]}}
- $in String OR Number OR Array val matches to value in specified array:
- {'json.field.path' : {'$in' : [val1, val2, val3]}}
- $nin - Not IN
- $strand String tokens OR String array val matches all tokens in specified array:
- {'json.field.path' : {'$strand' : [val1, val2, val3]}}
- $stror String tokens OR String array val matches any token in specified array:
- {'json.field.path' : {'$stror' : [val1, val2, val3]}}
- $exists Field existence matching:
- {'json.field.path' : {'$exists' : true|false}}
- $icase Case insensitive string matching:
- {'json.field.path' : {'$icase' : 'val1'}} //icase matching
Ignore case matching with '$in' operation:
- {'name' : {'$icase' : {'$in' : ['tHéâtre - театр', 'heLLo WorlD']}}}
For case insensitive matching you can create special type of string index.
NOTE: Negate operations: $not and $nin not using indexes
so they can be slow in comparison to other matching operations.
NOTE: Only one index can be used in search query operation.
QUERY HINTS (specified by `hints` argument):
- $max Maximum number in the result set
- $skip Number of skipped results in the result set
- $orderby Sorting order of query fields.
- $fields Set subset of fetched fields
Example:
hints: {
"$orderby" : { //ORDER BY field1 ASC, field2 DESC
"field1" : 1,
"field2" : -1
},
"$fields" : { //SELECT ONLY {_id, field1, field2}
"field1" : 1,
"field2" : 1
}
}
Many C API query examples can be found in `tcejdb/testejdb/t2.c` test case.
To traverse selected records cursor object is used:
- Cursor#next() Move cursor to the next record and returns true if next record exists.
- Cursor#hasNext() Returns true if cursor can be placed to the next record.
- Cursor#field(name) Retrieve value of the specified field of the current JSON object record.
- Cursor#object() Retrieve whole JSON object with all fields.
- Cursor#reset() Reset cursor to its initial state.
- Cursor#length Read-only property: Number of records placed into cursor.
- Cursor#pos Read/Write property: You can set cursor position: 0 <= pos < length
- Cursor#close() Closes cursor and free cursor resources. Cursor cant be used in closed state.
Call variations of find():
- find(cname, qobj, cb)
- find(cname, qobj, hints, cb)
- find(cname, qobj, qobjarr, cb)
- find(cname, qobj, qobjarr, hints, cb)
Arguments
- {String} cname Name of collection
- {Object} qobj Main JSON query object
- {Array}
[orarr]
Array of additional OR query objects (joined with OR predicate). - {Object}
[hints]
JSON object with query hints. - {Function} cb Callback args: (error, cursor, count)
cursor
: Cursor object to traverse records
count
: Total number of selected records
### dropStringIndex(cname, path, cb)
### dropIStringIndex(cname, path, cb)
### dropNumberIndex(cname, path, cb)
### dropArrayIndex(cname, path, cb)
Drop index of String|Number|Array type for JSON field path.
IString
is the special type of String index for case insensitive matching.
Arguments
- {String} cname Name of collection
- {String} path JSON field path
- {Function}
[cb]
Optional callback function. Callback args: (error)
EJDB C Library
One snippet intro
#include <tcejdb/ejdb.h>
static EJDB *jb;
int main() {
jb = ejdbnew();
if (!ejdbopen(jb, "addressbook", JBOWRITER | JBOCREAT | JBOTRUNC)) {
return 1;
}
//Get or create collection 'contacts'
EJCOLL *coll = ejdbcreatecoll(jb, "contacts", NULL);
bson bsrec;
bson_oid_t oid;
//Insert one record:
//JSON: {'name' : 'Bruce', 'phone' : '333-222-333', 'age' : 58}
bson_init(&bsrec);
bson_append_string(&bsrec, "name", "Bruce");
bson_append_string(&bsrec, "phone", "333-222-333");
bson_append_int(&bsrec, "age", 58);
bson_finish(&bsrec);
//Save BSON
ejdbsavebson(coll, &bsrec, &oid);
fprintf(stderr, "\nSaved Bruce");
bson_destroy(&bsrec);
//Now execute query
//QUERY: {'name' : {'$begin' : 'Bru'}} //Name starts with 'Bru' string
bson bq1;
bson_init_as_query(&bq1);
bson_append_start_object(&bq1, "name");
bson_append_string(&bq1, "$begin", "Bru");
bson_append_finish_object(&bq1);
bson_finish(&bq1);
EJQ *q1 = ejdbcreatequery(jb, &bq1, NULL, 0, NULL);
uint32_t count;
TCLIST *res = ejdbqrysearch(coll, q1, &count, 0, NULL);
fprintf(stderr, "\n\nRecords found: %d\n", count);
//Now print the result set records
for (int i = 0; i < TCLISTNUM(res); ++i) {
void *bsdata = TCLISTVALPTR(res, i);
bson_print_raw(stderr, bsdata, 0);
}
fprintf(stderr, "\n");
//Dispose result set
tclistdel(res);
//Dispose query
ejdbquerydel(q1);
bson_destroy(&bq1);
//Close database
ejdbclose(jb);
ejdbdel(jb);
return 0;
}
You can save this code in csnippet.c
And build:
gcc -std=c99 -Wall -pedantic -c -o csnippet.o csnippet.c
gcc -std=c99 -Wall -pedantic -o csnippet csnippet.o -ltcejdb
Building & Installation
Prerequisites
System libraries:
On Debian/Ubuntu linux you can install it as follows:
sudo apt-get install gcc libcunit1 libcunit1-dev zlib1g zlib1g-dev
Building
cd ./tcejdb
./configure --disable-bzip --prefix=<installation prefix> && make && make check
make install
- library name: tcejdb (with pkgconfig)
- main include header:
<tcejdb/ejdb.h>
C API
EJDB API presented in ejdb.h C header file.
JSON processing API: bson.h
Queries
/**
* Create query object.
* Sucessfully created queries must be destroyed with ejdbquerydel().
*
* EJDB queries inspired by MongoDB (mongodb.org) and follows same philosophy.
*
* - Supported queries:
* - Simple matching of String OR Number OR Array value:
* - {'json.field.path' : 'val', ...}
* - $not Negate operation.
* - {'json.field.path' : {'$not' : val}} //Field not equal to val
* - {'json.field.path' : {'$not' : {'$begin' : prefix}}} //Field not begins with val
* - $begin String starts with prefix
* - {'json.field.path' : {'$begin' : prefix}}
* - $gt, $gte (>, >=) and $lt, $lte for number types:
* - {'json.field.path' : {'$gt' : number}, ...}
* - $bt Between for number types:
* - {'json.field.path' : {'$bt' : [num1, num2]}}
* - $in String OR Number OR Array val matches to value in specified array:
* - {'json.field.path' : {'$in' : [val1, val2, val3]}}
* - $nin - Not IN
* - $strand String tokens OR String array val matches all tokens in specified array:
* - {'json.field.path' : {'$strand' : [val1, val2, val3]}}
* - $stror String tokens OR String array val matches any token in specified array:
* - {'json.field.path' : {'$stror' : [val1, val2, val3]}}
* - $exists Field existence matching:
* - {'json.field.path' : {'$exists' : true|false}}
* - $icase Case insensitive string matching:
* - {'json.field.path' : {'$icase' : 'val1'}} //icase matching
Ignore case matching with '$in' operation:
* - {'name' : {'$icase' : {'$in' : ['tHéâtre - театр', 'heLLo WorlD']}}}
* For case insensitive matching you can create special index of type: `JBIDXISTR`
*
* NOTE: Negate operations: $not and $nin not using indexes
* so they can be slow in comparison to other matching operations.
*
* NOTE: Only one index can be used in search query operation.
*
* QUERY HINTS (specified by `hints` argument):
* - $max Maximum number in the result set
* - $skip Number of skipped results in the result set
* - $orderby Sorting order of query fields.
* - $fields Set subset of fetched fields
* Example:
* hints: {
* "$orderby" : { //ORDER BY field1 ASC, field2 DESC
* "field1" : 1,
* "field2" : -1
* },
* "$fields" : { //SELECT ONLY {_id, field1, field2}
* "field1" : 1,
* "field2" : 1
* }
* }
*
* Many query examples can be found in `testejdb/t2.c` test case.
*
* @param EJDB database handle.
* @param qobj Main BSON query object.
* @param orqobjs Array of additional OR query objects (joined with OR predicate).
* @param orqobjsnum Number of OR query objects.
* @param hints BSON object with query hints.
* @return On success return query handle. On error returns NULL.
*/
EJDB_EXPORT EJQ* ejdbcreatequery(EJDB *jb, bson *qobj, bson *orqobjs, int orqobjsnum, bson *hints);
EJDB C Samples
You can find some code samples in: