Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the API synchronous #44

Merged
merged 3 commits into from
May 27, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 59 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,39 +95,38 @@ const filter = {
};

// More on index/collection parameters later
engine.register('index', 'collection', filter)
.then(result => {
// The filter identifier depends on a random seed (see below)
// For now, let's pretend its value is 5db7052792b18cb2
console.log(`Filter identifier: ${result.id}`);

// *** Now, let's test data with our engine ***

// Returns: [] (distance is greater than 500m)
console.log(engine.test('index', 'collection', {
position: {
lat: 43.6073913,
lon: 5.7
}
}));

// Returns: ['5db7052792b18cb2']
console.log(engine.test('index', 'collection', {
position: {
lat: 43.608,
lon: 3.905
}
}));


// Returns: [] (the geopoint is not stored in a "position" field)
console.log(engine.test('index', 'collection', {
point: {
lat: 43.608,
lon: 3.905
}
}));
});
const result = engine.register('index', 'collection', filter);

// The filter identifier depends on a random seed (see below)
// For now, let's pretend its value is 5db7052792b18cb2
console.log(`Filter identifier: ${result.id}`);

// *** Now, let's test data with our engine ***

// Returns: [] (distance is greater than 500m)
console.log(engine.test('index', 'collection', {
position: {
lat: 43.6073913,
lon: 5.7,
},
}));

// Returns: ['5db7052792b18cb2']
console.log(engine.test('index', 'collection', {
position: {
lat: 43.608,
lon: 3.905,
},
}));


// Returns: [] (the geopoint is not stored in a "position" field)
console.log(engine.test('index', 'collection', {
point: {
lat: 43.608,
lon: 3.905,
},
}));
```

## Install
Expand Down Expand Up @@ -175,42 +174,35 @@ In the following example, we provide a fixed random seed. Replaying this example
```js
const Koncorde = require('koncorde');

const
seed = Buffer.from('ac1bb751a1e5b3dce4a5d58e3e5e317677f780f57f8ca27b624345808b3e0e86', 'hex'),
engine = new Koncorde({seed});
const seed = Buffer.from(
'ac1bb751a1e5b3dce4a5d58e3e5e317677f780f57f8ca27b624345808b3e0e86',
'hex');
const engine = new Koncorde({seed});

// filter1 and filter2 are equivalent
const
filter1 = {
and:[
{equals: {firstname: 'Grace'}},
{exists: {field: 'hobby'}}
]
const filter1 = {
and: [
{ equals: { firstname: 'Grace' } },
{ exists: { field: 'hobby' } },
]
};
const filter2 = {
not: {
bool: {
should_not: [
{ in: { firstname: [ 'Grace' ] } },
{ exists: { field: 'hobby' } },
],
},
filter2 = {
not: {
bool: {
should_not: [
{in: {firstname: ['Grace']}},
{exists: {field: 'hobby'}}
]
}
}
};

let filterId1;

engine.register('index', 'collection', filter1)
.then(result => {
filterId1 = result.id;
return engine.register('index', 'collection', filter2);
})
.then(result => {
console.log(`Filter ID 1: ${filterId1}, Filter ID 2: ${result.id}, Equals: ${filterId1 === result.id}`);
});
},
};

const subscription1 = engine.register('index', 'collection', filter1);
const subscription2 = engine.register('index', 'collection', filter2);

// Prints:
// Filter ID 1: b4ee9ece4d7b1398, Filter ID 2: b4ee9ece4d7b1398, Equals: true
console.log(`Filter ID 1: ${subscription1.id}, Filter ID 2: ${subscription2.id}, Equals: ${subscription1.id === subscription2.id}`);
```

## Field syntax
Expand Down Expand Up @@ -1280,8 +1272,7 @@ An `array` of index names.

### `normalize`

Returns a promise resolved if the provided filter are well-formed.
The resolved object contains the provided filter in its canonical form, along with the corresponding filter unique identifier.
Returns an object containing the provided filter in its canonical form, along with the corresponding filter unique identifier.

This method does not modify the internal storage. To save a filter, the [store](#store) method must be called afterward.
If you do not need the filter unique identifier prior to save a filter in the engine, then consider using the all-in-one [register](#register) method instead.
Expand All @@ -1298,7 +1289,7 @@ If you do not need the filter unique identifier prior to save a filter in the en

#### Returns

A `promise` resolving to an object containing the following attributes:
An object containing the following attributes:

* `index`: data index name
* `collection`: data collection name
Expand All @@ -1323,7 +1314,7 @@ Registers a filter to the engine instance. This method is equivalent to executin

#### Returns

A `promise` resolving to an object containing the following attributes:
An object containing the following attributes:

* `id`: the filter unique identifier
* `diff`: `false` if the filter already exists in the engine. Otherwise, contains an object with the canonical version of the provided filter
Expand All @@ -1342,10 +1333,6 @@ Removes all references to a given filter from the engine.
|------|------|----------------------------------|
|`filterId`|`string`| Filter unique ID. Obtained by using `register`|

#### Returns

A `promise` resolved once the filter has been completely removed from the engine.

---

### `store`
Expand Down Expand Up @@ -1405,7 +1392,7 @@ Tests the provided filter without storing it in the engine, to check whether it

#### Returns

A resolved promise if the provided filter is valid, or a rejected one with the appropriate error object otherwise.
Throws with an appropriate error if the provided filter is invalid.

---

Expand Down
22 changes: 11 additions & 11 deletions benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function removeFilters() {
console.log(`\tFilters removal: time = ${(Date.now() - removalStart)/1000}s`);
}

async function test (name, generator, document) {
function test (name, generator, document) {
const baseHeap = v8.getHeapStatistics().total_heap_size;

console.log(`\n> Benchmarking keyword: ${name}`);
Expand All @@ -56,7 +56,7 @@ async function test (name, generator, document) {
for (let i = 0;i < max; i++) {
// Using the filter name as a collection to isolate
// benchmark calculation per keyword
filters.push((await koncorde.register('i', name, generator())).id);
filters.push(koncorde.register('i', name, generator()).id);
}

const filterEndTime = (Date.now() - filterStartTime) / 1000;
Expand All @@ -65,18 +65,18 @@ async function test (name, generator, document) {
matching(name, document);
}

async function run () {
await test(
function run () {
test(
'equals',
() => ({equals: {str: rgen.string(engine, 20)}}),
{ str: rgen.string(engine, 20) });

await test(
test(
'exists',
() => ({exists: {field: rgen.string(engine, 20)}}),
{ [rgen.string(engine, 20)]: true });

await test('geoBoundingBox',
test('geoBoundingBox',
() => {
const pos = georandom.position();

Expand All @@ -93,7 +93,7 @@ async function run () {
},
{ point: [0, 0] });

await test('geoDistance',
test('geoDistance',
() => {
const pos = georandom.position();

Expand All @@ -106,7 +106,7 @@ async function run () {
},
{ point: [0, 0] });

await test('geoDistanceRange',
test('geoDistanceRange',
() => {
const pos = georandom.position();

Expand All @@ -120,7 +120,7 @@ async function run () {
},
{ point: [0, 0] });

await test('geoPolygon (10 vertices)',
test('geoPolygon (10 vertices)',
() => {
const polygon = georandom
.polygon(1)
Expand All @@ -137,7 +137,7 @@ async function run () {
},
{ point: [0, 0] });

await test('in (5 random values)',
test('in (5 random values)',
() => {
const values = [];

Expand All @@ -149,7 +149,7 @@ async function run () {
},
{ str: rgen.string(engine, 20) });

await test('range (random bounds)',
test('range (random bounds)',
() => {
const bound = rgen.int(engine);

Expand Down
18 changes: 9 additions & 9 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ class Koncorde {
* Checks if the provided filter is valid
*
* @param {object} filter
* @return {Promise<Object>}
* @return {Object}
*/
async validate (filter) {
validate (filter) {
return this.transformer.check(filter);
}

Expand All @@ -74,10 +74,10 @@ class Koncorde {
* @param {string} index
* @param {string} collection
* @param {object} filters
* @return {Promise}
* @return {Object}
*/
async register (index, collection, filter) {
const normalized = await this.transformer.normalize(filter);
register (index, collection, filter) {
const normalized = this.transformer.normalize(filter);
return this.storage.store(index, collection, normalized);
}

Expand All @@ -90,10 +90,10 @@ class Koncorde {
* @param {string} index index
* @param {[type]} collection collection
* @param {[type]} filter filter
* @return {Promise.<{index: String, collection: String, id: String, normalized: Object}>}
* @return {{index: String, collection: String, id: String, normalized: Object}}
*/
async normalize(index, collection, filter) {
const normalized = await this.transformer.normalize(filter);
normalize(index, collection, filter) {
const normalized = this.transformer.normalize(filter);

return {
collection,
Expand Down Expand Up @@ -196,7 +196,7 @@ class Koncorde {
/**
* Converts a distance string value to a number of meters
* @param {string} distance - client-provided distance
* @returns {number} resolves to converted distance
* @returns {number} converted distance
*/
static convertDistance(distance) {
return convertDistance(distance);
Expand Down
3 changes: 1 addition & 2 deletions lib/transform/canonical.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

const Combinatorics = require('js-combinatorics');

const { BadRequestError } = require('kuzzle-common-objects');
const { Espresso } = require('espresso-logic-minimizer');

const strcmp = require('../util/stringCompare');
Expand Down Expand Up @@ -66,7 +65,7 @@ class Canonical {

const conditions = this._extractConditions(filters);
if (this.config.maxMinTerms && conditions.length > this.config.maxMinTerms) {
throw new BadRequestError('Maximum number of sub conditions reached.');
throw new Error('Maximum number of sub conditions reached.');
}

const normalized = this._normalize(filters, conditions);
Expand Down
16 changes: 1 addition & 15 deletions lib/transform/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@
* limitations under the License.
*/

const {
KuzzleError,
InternalError: KuzzleInternalError
} = require('kuzzle-common-objects');

const Standardizer = require('./standardize');
const Canonical = require('./canonical');

Expand All @@ -49,16 +44,7 @@ class Transformer {
normalize(filters) {
const standardized = this.standardizer.standardize(filters);

try {
return this.canonical.convert(standardized);
}
catch (e) {
if (e instanceof KuzzleError) {
throw e;
}

throw new KuzzleInternalError(e);
}
return this.canonical.convert(standardized);
}

/**
Expand Down
Loading