Comparing version
@@ -62,9 +62,9 @@ 'use strict'; | ||
// Default to index lang. | ||
// Default index lang. | ||
options.lang = options.lang || this.lang; | ||
// Accept single document. | ||
// Rationalize input : single document into an array. | ||
documents = _.isArray(documents) ? documents : [documents]; | ||
// Apply a custom input formatter. | ||
// Apply custom input formatter if any. | ||
if (this.formatters.input) documents = documents.map(this.formatters.input); | ||
@@ -88,5 +88,14 @@ | ||
lang: options.lang, | ||
fields: _.map(document, function (value, key) { | ||
return { name: key, value: value }; | ||
}) | ||
// REM : multi-valued fields (when value is an array) | ||
// should be flattened into several "fields" entries. | ||
// Hence the reduce. | ||
fields: _.reduce(document, function (accumulator, values, key) { | ||
// rationalize input | ||
if (!_.isArray(values)) values = [ values ]; | ||
// convert into field entries | ||
values.forEach(function(value) { | ||
accumulator.push({ name: key, value: value }); | ||
}); | ||
return accumulator; | ||
}, []) | ||
}; | ||
@@ -93,0 +102,0 @@ } |
{ | ||
"name": "oss-odm", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"description": "Object document mapper for Open Search Server.", | ||
@@ -23,13 +23,13 @@ "main": "index.js", | ||
"homepage": "https://github.com/lemonde/oss-odm", | ||
"dependencies": { | ||
"async": "~0.9.0", | ||
"lodash": "~3.7.0" | ||
}, | ||
"devDependencies": { | ||
"node-oss-client": "^0.3.0", | ||
"sinon-chai": "^2.5.0", | ||
"chai": "^1.9.1", | ||
"mocha": "^1.18.2", | ||
"sinon": "^1.9.0" | ||
}, | ||
"dependencies": { | ||
"async": "^0.2.10", | ||
"lodash": "^2.4.1" | ||
"node-oss-client": "~1.0.0", | ||
"sinon-chai": "~2.7.0", | ||
"chai": "~2.3.0", | ||
"mocha": "~2.2.4", | ||
"sinon": "~1.14.1" | ||
} | ||
} | ||
} |
# oss-odm [](https://travis-ci.org/lemonde/oss-odm) | ||
Object document mapper for Open Search Server. | ||
Object document mapper for [Open Search Server](http://www.open-search-server.com/). | ||
See also parent module [node-oss-client](https://github.com/lemonde/node-oss-client). | ||
## Install | ||
@@ -197,10 +200,18 @@ | ||
Note : if an array is provided as value, it triggers a multi-valued field insertion. | ||
```js | ||
index.create([ | ||
{ title: 'My first document' }, | ||
{ title: 'My second document' } | ||
{ | ||
title: 'My first document', | ||
foo: 'bar' | ||
}, | ||
{ | ||
title: 'My second document', | ||
ids: [23, 34] | ||
} | ||
], function (err) { ... }); | ||
``` | ||
Some options are avalaibles: | ||
Some options are available: | ||
@@ -227,3 +238,3 @@ #### lang | ||
Some options are avalaibles: | ||
Some options are available: | ||
@@ -248,3 +259,3 @@ #### field | ||
Some options are avalaibles: | ||
Some options are available: | ||
@@ -348,4 +359,5 @@ #### lang | ||
## License | ||
MIT |
@@ -5,6 +5,9 @@ var oss = require('node-oss-client'); | ||
var sinon = require('sinon'); | ||
var _ = require('lodash'); | ||
describe('Index', function () { | ||
describe('#create', function () { | ||
var indexer1, indexer2, index, documents; | ||
var expectedOssInput, expectedOssInputFields1, expectedOssInputFields2; | ||
@@ -20,4 +23,37 @@ beforeEach(function () { | ||
documents = [{ my_custom_key: 'bar' }]; | ||
documents = [ | ||
{ | ||
foo: 'bar', | ||
otk: 7 | ||
}, | ||
// another document, to test multi-document capabilities | ||
{ | ||
bar: 'baz', | ||
otk: 10, | ||
targets: [ 7, 'all' ] // this tests multi-valued inputs | ||
} | ||
]; | ||
// the documents, as expected to be presented to OSS | ||
expectedOssInputFields1 = [ | ||
{ name: 'foo', value: 'bar' }, | ||
{ name: 'otk', value: 7 } | ||
]; | ||
expectedOssInputFields2 = [ | ||
{ name: 'bar', value: 'baz' }, | ||
{ name: 'otk', value: 10 }, | ||
{ name: 'targets', value: 7 }, //< note the flattening | ||
{ name: 'targets', value: 'all' } //< | ||
]; | ||
expectedOssInput = [ | ||
{ | ||
lang: 'ENGLISH', | ||
fields: expectedOssInputFields1 | ||
}, | ||
{ | ||
lang: 'ENGLISH', | ||
fields: expectedOssInputFields2 | ||
} | ||
]; | ||
function createOssClient() { | ||
@@ -30,17 +66,6 @@ var client = oss.createClient(); | ||
it('should create documents on each indexer', function (done) { | ||
it('should format to correct OSS inputs', function (done) { | ||
index.create(documents, function (err) { | ||
if (err) return done(err); | ||
expect(indexer1.documents.create).to.be.calledWith('my_index', [{ | ||
lang: 'ENGLISH', | ||
fields: [ | ||
{ name: 'my_custom_key', value: 'bar' } | ||
] | ||
}]); | ||
expect(indexer2.documents.create).to.be.calledWith('my_index', [{ | ||
lang: 'ENGLISH', | ||
fields: [ | ||
{ name: 'my_custom_key', value: 'bar' } | ||
] | ||
}]); | ||
expect(indexer1.documents.create).to.have.been.calledWith('my_index', expectedOssInput); | ||
done(); | ||
@@ -50,20 +75,22 @@ }); | ||
it('should emit "create" event', function (done) { | ||
var spy = sinon.spy(); | ||
index.on('create', spy); | ||
describe('when given a single document', function() { | ||
it('should format to correct OSS inputs', function (done) { | ||
var singleDocument = documents[1]; | ||
var singleExpectedOssInput = [{ | ||
lang: 'ENGLISH', | ||
fields: expectedOssInputFields2 | ||
}]; | ||
index.create(singleDocument, function (err) { | ||
if (err) return done(err); | ||
expect(indexer1.documents.create).to.have.been.calledWith('my_index', singleExpectedOssInput); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should create documents on each indexer', function (done) { | ||
index.create(documents, function (err) { | ||
if (err) return done(err); | ||
expect(spy).to.be.calledWith(indexer1, 'my_index', [{ | ||
lang: 'ENGLISH', | ||
fields: [ | ||
{ name: 'my_custom_key', value: 'bar' } | ||
] | ||
}]); | ||
expect(spy).to.be.calledWith(indexer2, 'my_index', [{ | ||
lang: 'ENGLISH', | ||
fields: [ | ||
{ name: 'my_custom_key', value: 'bar' } | ||
] | ||
}]); | ||
expect(indexer1.documents.create).to.have.been.calledWith('my_index', expectedOssInput); | ||
expect(indexer2.documents.create).to.have.been.calledWith('my_index', expectedOssInput); | ||
done(); | ||
@@ -73,18 +100,10 @@ }); | ||
it('should emit an "error" event', function (done) { | ||
it('should emit the "create" event', function (done) { | ||
var spy = sinon.spy(); | ||
index.on('error', spy); | ||
index.on('create', spy); | ||
var indexError = new Error('Indexing error.'); | ||
indexer1.documents.create.restore(); | ||
sinon.stub(indexer1.documents, 'create').yields(indexError); | ||
index.create(documents, function (err) { | ||
if (err) return done(err); | ||
expect(spy).to.be.calledWith(indexError, indexer1, 'my_index', [{ | ||
lang: 'ENGLISH', | ||
fields: [ | ||
{ name: 'my_custom_key', value: 'bar' } | ||
] | ||
}]); | ||
expect(spy).to.have.been.calledWith(indexer1, 'my_index', expectedOssInput); | ||
expect(spy).to.have.been.calledWith(indexer2, 'my_index', expectedOssInput); | ||
done(); | ||
@@ -94,38 +113,56 @@ }); | ||
it('should be possible to add options', function (done) { | ||
index.create(documents, { lang: 'FRENCH' }, function (err) { | ||
if (err) return done(err); | ||
expect(indexer1.documents.create).to.be.calledWith('my_index', [{ | ||
lang: 'FRENCH', | ||
fields: [ | ||
{ name: 'my_custom_key', value: 'bar' } | ||
] | ||
}]); | ||
expect(indexer2.documents.create).to.be.calledWith('my_index', [{ | ||
lang: 'FRENCH', | ||
fields: [ | ||
{ name: 'my_custom_key', value: 'bar' } | ||
] | ||
}]); | ||
done(); | ||
describe('on error', function() { | ||
it('should emit an "error" event', function (done) { | ||
var spy = sinon.spy(); | ||
index.on('error', spy); | ||
var indexError = new Error('Indexing error.'); | ||
indexer1.documents.create.restore(); | ||
sinon.stub(indexer1.documents, 'create').yields(indexError); | ||
index.create(documents, function (err) { | ||
if (err) return done(err); | ||
expect(spy).to.have.been.calledWith(indexError, indexer1, 'my_index', expectedOssInput); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should be possible to add a custom formatter', function (done) { | ||
index.formatters.input = function (document) { | ||
document.x = 'y'; | ||
return document; | ||
}; | ||
describe('options', function() { | ||
var specificExpectedOssInput; | ||
beforeEach(function() { | ||
specificExpectedOssInput = _.cloneDeep(expectedOssInput); | ||
}); | ||
index.create(documents, { lang: 'FRENCH' }, function (err) { | ||
if (err) return done(err); | ||
expect(indexer1.documents.create).to.be.calledWith('my_index', [{ | ||
lang: 'FRENCH', | ||
fields: [ | ||
{ name: 'my_custom_key', value: 'bar' }, | ||
{ name: 'x', value: 'y' } | ||
] | ||
}]); | ||
done(); | ||
describe('lang', function() { | ||
it('should be handled', function (done) { | ||
specificExpectedOssInput[0].lang = 'FRENCH'; | ||
specificExpectedOssInput[1].lang = 'FRENCH'; | ||
index.create(documents, { lang: 'FRENCH' }, function (err) { | ||
if (err) return done(err); | ||
expect(indexer1.documents.create).to.have.been.calledWith('my_index', specificExpectedOssInput); | ||
expect(indexer2.documents.create).to.have.been.calledWith('my_index', specificExpectedOssInput); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('custom formatter', function() { | ||
it('should be handled', function (done) { | ||
index.formatters.input = function (document) { | ||
document.x = 'y'; | ||
return document; | ||
}; | ||
specificExpectedOssInput[0].fields.push({ name: 'x', value: 'y' }); | ||
specificExpectedOssInput[1].fields.push({ name: 'x', value: 'y' }); | ||
index.create(documents, function (err) { | ||
if (err) return done(err); | ||
expect(indexer1.documents.create).to.have.been.calledWith('my_index', specificExpectedOssInput); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -158,7 +195,7 @@ }); | ||
if (err) return done(err); | ||
expect(indexer1.documents.destroy).to.be.calledWith('my_index', { | ||
expect(indexer1.documents.destroy).to.have.been.calledWith('my_index', { | ||
field: 'id', | ||
values: values | ||
}); | ||
expect(indexer2.documents.destroy).to.be.calledWith('my_index', { | ||
expect(indexer2.documents.destroy).to.have.been.calledWith('my_index', { | ||
field: 'id', | ||
@@ -177,7 +214,7 @@ values: values | ||
if (err) return done(err); | ||
expect(spy).to.be.calledWith(indexer1, 'my_index', { | ||
expect(spy).to.have.been.calledWith(indexer1, 'my_index', { | ||
field: 'id', | ||
values: values | ||
}); | ||
expect(spy).to.be.calledWith(indexer2, 'my_index', { | ||
expect(spy).to.have.been.calledWith(indexer2, 'my_index', { | ||
field: 'id', | ||
@@ -200,3 +237,3 @@ values: values | ||
if (err) return done(err); | ||
expect(spy).to.be.calledWith(indexError, indexer1, 'my_index', { | ||
expect(spy).to.have.been.calledWith(indexError, indexer1, 'my_index', { | ||
field: 'id', | ||
@@ -212,7 +249,7 @@ values: values | ||
if (err) return done(err); | ||
expect(indexer1.documents.destroy).to.be.calledWith('my_index', { | ||
expect(indexer1.documents.destroy).to.have.been.calledWith('my_index', { | ||
field: 'id_test', | ||
values: values | ||
}); | ||
expect(indexer2.documents.destroy).to.be.calledWith('my_index', { | ||
expect(indexer2.documents.destroy).to.have.been.calledWith('my_index', { | ||
field: 'id_test', | ||
@@ -249,3 +286,3 @@ values: values | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -264,3 +301,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -282,3 +319,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -301,3 +338,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -344,3 +381,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -369,3 +406,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -407,3 +444,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -439,3 +476,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -464,3 +501,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -561,3 +598,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -607,3 +644,3 @@ query: 'my query', | ||
expect(res.documents).to.eql([]); | ||
expect(searcher.search).to.be.calledWith('my_index', { | ||
expect(searcher.search).to.have.been.calledWith('my_index', { | ||
lang: 'ENGLISH', | ||
@@ -610,0 +647,0 @@ query: 'my query', |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
44341
6.47%10
11.11%1150
3.51%360
3.45%1
Infinity%+ Added
+ Added
- Removed
- Removed
Updated
Updated