UNPKG

itemsjs

Version:

Created to perform fast search on small json dataset (up to 1000 elements).

477 lines (365 loc) 10.8 kB
'use strict'; const assert = require('assert'); const Facets = require('./../src/facets'); const helpers = require('./../src/helpers'); const FastBitSet = require('fastbitset'); const items = [{ id: 1, name: 'movie1', tags: ['a', 'b', 'c', 'd'], actors: ['john', 'alex'], category: 'drama' }, { id: 2, name: 'movie2', tags: ['a', 'e', 'f'], actors: ['john', 'brad'], category: 'comedy' }, { id: 3, name: 'movie3', tags: ['a', 'c'], actors: ['jeff'], category: 'comedy' }, { id: 4, name: 'movie4', tags: ['c', 'a', 'z'], actors: ['jean'], category: 'drama' }]; describe('indexing', function() { }); describe('conjunctive search', function() { const aggregations = { tags: { //title: 'Tags', conjunction: true, }, actors: { title: 'Stars', conjunction: true, }, category: { title: 'Category', conjunction: true, } }; const facets = new Facets(items, aggregations); const itemsjs = require('./../index')(items, { aggregations: aggregations }); it('checks index', function test(done) { const result = facets.index(); assert.deepEqual(result.data.tags.a, [1, 2, 3, 4]); assert.deepEqual(result.bits_data.tags.a.array(), [1, 2, 3, 4]); assert.deepEqual(result.data.tags.b, [1]); assert.deepEqual(result.bits_data.tags.b.array(), [1]); assert.deepEqual(result.data.tags.c, [1, 3, 4]); assert.deepEqual(result.data.tags.d, [1]); assert.deepEqual(result.data.tags.e, [2]); assert.deepEqual(result.data.tags.z, [4]); assert.deepEqual(result.data.actors.jean, [4]); assert.deepEqual(result.bits_data.actors.jean.array(), [4]); assert.deepEqual(result.data.actors.john, [1, 2]); assert.deepEqual(result.bits_data.actors.john.array(), [1, 2]); done(); }); it('returns facets for two fields (tags, actors)', function test(done) { const input = { filters: { tags: ['c'] } }; let result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, [1, 3, 4]); assert.deepEqual(result.data.tags.c, [1, 3, 4]); assert.deepEqual(result.data.tags.e, []); assert.deepEqual(result.data.actors.john, [1]); assert.deepEqual(result.data.category.comedy, [3]); const ids = helpers.facets_ids(result['bits_data_temp'], input.filters, aggregations); assert.deepEqual(ids.array(), [1, 3, 4]); const buckets = helpers.getBuckets(result, input, aggregations); //console.log(buckets.tags.buckets); assert.deepEqual(buckets.tags.buckets[0].doc_count, 3); assert.deepEqual(buckets.tags.buckets[0].key, 'c'); assert.deepEqual(buckets.tags.title, 'Tags'); assert.deepEqual(buckets.actors.title, 'Stars'); assert.deepEqual(buckets.category.title, 'Category'); result = itemsjs.search(input); assert.deepEqual(result.pagination.total, 3); // omit _id in search result //assert.deepEqual(result.data.items[0]._id, undefined); assert.deepEqual(result.data.aggregations.tags.buckets[0].doc_count, 3); assert.deepEqual(result.data.aggregations.tags.buckets[0].key, 'c'); done(); }); it('checks if search is working on copy data', function test(done) { const input = { filters: { tags: ['e'] } }; const result = facets.search(input, { test: true }); //assert.deepEqual(result.bits_data.tags.a.array(), []); assert.deepEqual(result.data.tags.a, [2]); assert.deepEqual(result.data.tags.e, [2]); //assert.deepEqual(result.bits_data.tags.e.array(), [2]); //assert.deepEqual(result.data.actors.john, [1]); done(); }); it('returns facets for empty input', function test(done) { let input = { filters: { } }; let result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, [1, 2, 3, 4]); assert.deepEqual(result.data.tags.e, [2]); const ids = helpers.facets_ids(result['bits_data_temp'], input.filters, aggregations); assert.deepEqual(ids, null); result = itemsjs.search(input); assert.deepEqual(result.pagination.total, 4); // omit _id in search result //assert.deepEqual(result.data.items[0]._id, undefined); assert.deepEqual(result.data.aggregations.tags.buckets[0].doc_count, 4); assert.deepEqual(result.data.aggregations.tags.buckets[0].key, 'a'); input = { filters: { tags: [] } }; result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, [1, 2, 3, 4]); assert.deepEqual(result.data.tags.e, [2]); done(); }); xit('returns facets for not existed filters (does not exist in index)', function test(done) { const input = { filters: { tags: ['kkk'] } }; const result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, []); assert.deepEqual(result.data.tags.e, []); done(); }); it('returns facets for cross filters', function test(done) { const input = { filters: { tags: ['a'], actors: ['john'] } }; const result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, [1, 2]); assert.deepEqual(result.data.tags.e, [2]); assert.deepEqual(result.data.actors.john, [1, 2]); assert.deepEqual(result.data.actors.jean, []); done(); }); }); describe('disjunctive search', function() { const aggregations = { tags: { conjunction: false, }, actors: { conjunction: false, }, category: { conjunction: false, } }; const facets = new Facets(items, aggregations); it('returns facets', function test(done) { const input = { filters: { tags: ['c'] } }; const result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, [1, 2, 3, 4]); assert.deepEqual(result.data.tags.c, [1, 3, 4]); assert.deepEqual(result.data.tags.e, [2]); assert.deepEqual(result.data.actors.john, [1]); done(); }); it('returns facets for two filters', function test(done) { const input = { filters: { tags: ['z', 'f'] } }; const result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, [1, 2, 3, 4]); assert.deepEqual(result.data.tags.c, [1, 3, 4]); assert.deepEqual(result.data.tags.f, [2]); assert.deepEqual(result.data.tags.z, [4]); assert.deepEqual(result.data.actors.brad, [2]); assert.deepEqual(result.data.actors.jean, [4]); assert.deepEqual(result.data.actors.brad, [2]); assert.deepEqual(result.data.category.comedy, [2]); assert.deepEqual(result.data.category.drama, [4]); done(); }); }); describe('disjunctive and conjunctive search', function() { const aggregations = { tags: { conjunction: true, }, actors: { conjunction: true, }, category: { conjunction: false } }; const facets = new Facets(items, aggregations); it('returns facets', function test(done) { const input = { filters: { tags: ['c'] } }; const result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, [1, 3, 4]); assert.deepEqual(result.data.tags.e, []); assert.deepEqual(result.data.actors.john, [1]); assert.deepEqual(result.data.category.comedy, [3]); done(); }); it('returns facets for cross filters', function test(done) { const input = { filters: { tags: ['c'], category: ['drama'] } }; const result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, [1, 4]); assert.deepEqual(result.data.tags.c, [1, 4]); assert.deepEqual(result.data.tags.e, []); assert.deepEqual(result.data.actors.john, [1]); assert.deepEqual(result.data.actors.alex, [1]); assert.deepEqual(result.data.category.comedy, [3]); assert.deepEqual(result.data.category.drama, [1, 4]); const ids = helpers.facets_ids(result['bits_data_temp'], input.filters, aggregations); assert.deepEqual(ids.array(), [1, 4]); done(); }); }); describe('generates facets crossed with query', function() { const aggregations = { tags: { conjunction: true, }, actors: { conjunction: true, }, category: { conjunction: false } }; const facets = new Facets(items, aggregations); const itemsjs = require('./../index')(items, { aggregations: aggregations, searchableFields: ['actors'], }); it('returns facets for searched ids', function test(done) { let input = { filters: { tags: ['c'] } }; let result = facets.search(input, { test: true }); assert.deepEqual(result.data.tags.a, [1, 3, 4]); assert.deepEqual(result.data.tags.e, []); assert.deepEqual(result.data.actors.john, [1]); assert.deepEqual(result.data.category.comedy, [3]); input = { filters: { tags: ['c'] } }; result = facets.search(input, { query_ids: new FastBitSet([1]), test: true }); assert.deepEqual(result.data.tags.a, [1]); assert.deepEqual(result.data.tags.e, []); assert.deepEqual(result.data.actors.john, [1]); assert.deepEqual(result.data.category.comedy, []); done(); }); it('returns facets for searched ids', function test(done) { const input = { query: 'john' }; const result = itemsjs.search(input); //console.log(result.data); //console.log(result.data.aggregations.tags); assert.deepEqual(result.data.aggregations.tags.buckets[0].key, 'a'); assert.deepEqual(result.data.aggregations.tags.buckets[0].doc_count, 2); done(); }); }); describe('generates symetrical disjunctive facets (SergeyRe)', function() { const aggregations = { a: { conjunction: false, }, b: { conjunction: false, }, }; const items = [ { a: 1, b: 3 }, { a: 1, b: 4 }, { a: 2, b: 3 }, { a: 2, b: 4 } ] const facets = new Facets(items, aggregations); const itemsjs = require('./../index')(items, { aggregations: aggregations, }); it('provides symetrical result', function test(done) { let input = { filters: { b: [3], a: [1] } }; let result = facets.search(input, { test: true }); assert.deepEqual(result.data.a['1'], [1]); assert.deepEqual(result.data.a['2'], [3]); assert.deepEqual(result.data.b['3'], [1]); assert.deepEqual(result.data.b['4'], [2]); done(); }); });