Socket
Socket
Sign inDemoInstall

lunr

Package Overview
Dependencies
Maintainers
1
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lunr - npm Package Compare versions

Comparing version 2.2.1 to 2.3.0

2

.eslintrc.json

@@ -28,3 +28,3 @@ {

"serializable", "tis", "twas", "int", "args", "unshift", "plugins", "upsert",
"upserting", "readonly", "baz", "tokenization"
"upserting", "readonly", "baz", "tokenization", "lunrjs", "com"
]

@@ -31,0 +31,0 @@ }

# Changelog
## 2.3.0
* Add support for build time field and document boosts.
* Add support for indexing nested document fields using field extractors.
* Prevent usage of problematic characters in field names, thanks [Stephane Mankowski](https://github.com/miraks31).
* Fix bug when using an array of tokens in a single query term, thanks [Michael Manukyan](https://github.com/mike1808).
## 2.2.1

@@ -4,0 +11,0 @@

@@ -32,3 +32,4 @@ /*!

this._ref = "id"
this._fields = []
this._fields = Object.create(null)
this._documents = Object.create(null)
this.invertedIndex = Object.create(null)

@@ -64,2 +65,16 @@ this.fieldTermFrequencies = {}

/**
* A function that is used to extract a field from a document.
*
* Lunr expects a field to be at the top level of a document, if however the field
* is deeply nested within a document an extractor function can be used to extract
* the right field for indexing.
*
* @callback fieldExtractor
* @param {object} doc - The document being added to the index.
* @returns {?(string|object|object[])} obj - The object that will be indexed for this field.
* @example <caption>Extracting a nested field</caption>
* function (doc) { return doc.nested.field }
*/
/**
* Adds a field to the list of document fields that will be indexed. Every document being

@@ -72,6 +87,18 @@ * indexed should have this field. Null values for this field in indexed documents will

*
* @param {string} field - The name of a field to index in all documents.
* Fields can be boosted at build time. This allows terms within that field to have more
* importance when ranking search results. Use a field boost to specify that matches within
* one field are more important than other fields.
*
* @param {string} fieldName - The name of a field to index in all documents.
* @param {object} attributes - Optional attributes associated with this field.
* @param {number} [attributes.boost=1] - Boost applied to all terms within this field.
* @param {fieldExtractor} [attributes.extractor] - Function to extract a field from a document.
* @throws {RangeError} fieldName cannot contain unsupported characters '/'
*/
lunr.Builder.prototype.field = function (field) {
this._fields.push(field)
lunr.Builder.prototype.field = function (fieldName, attributes) {
if (/\//.test(fieldName)) {
throw new RangeError ("Field '" + fieldName + "' contains illegal character '/'")
}
this._fields[fieldName] = attributes || {}
}

@@ -118,12 +145,20 @@

*
* Entire documents can be boosted at build time. Applying a boost to a document indicates that
* this document should rank higher in search results than other documents.
*
* @param {object} doc - The document to add to the index.
* @param {object} attributes - Optional attributes associated with this document.
* @param {number} [attributes.boost=1] - Boost applied to all terms within this document.
*/
lunr.Builder.prototype.add = function (doc) {
var docRef = doc[this._ref]
lunr.Builder.prototype.add = function (doc, attributes) {
var docRef = doc[this._ref],
fields = Object.keys(this._fields)
this._documents[docRef] = attributes || {}
this.documentCount += 1
for (var i = 0; i < this._fields.length; i++) {
var fieldName = this._fields[i],
field = doc[fieldName],
for (var i = 0; i < fields.length; i++) {
var fieldName = fields[i],
extractor = this._fields[fieldName].extractor,
field = extractor ? extractor(doc) : doc[fieldName],
tokens = this.tokenizer(field, {

@@ -159,4 +194,4 @@ fields: [fieldName]

for (var k = 0; k < this._fields.length; k++) {
posting[this._fields[k]] = Object.create(null)
for (var k = 0; k < fields.length; k++) {
posting[fields[k]] = Object.create(null)
}

@@ -212,5 +247,7 @@

for (var i = 0; i < this._fields.length; i++) {
var field = this._fields[i]
accumulator[field] = accumulator[field] / documentsWithField[field]
var fields = Object.keys(this._fields)
for (var i = 0; i < fields.length; i++) {
var fieldName = fields[i]
accumulator[fieldName] = accumulator[fieldName] / documentsWithField[fieldName]
}

@@ -234,3 +271,3 @@

var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),
field = fieldRef.fieldName,
fieldName = fieldRef.fieldName,
fieldLength = this.fieldLengths[fieldRef],

@@ -242,2 +279,6 @@ fieldVector = new lunr.Vector,

var fieldBoost = this._fields[fieldName].boost || 1,
docBoost = this._documents[fieldRef.docRef].boost || 1
for (var j = 0; j < termsLength; j++) {

@@ -256,3 +297,5 @@ var term = terms[j],

score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (fieldLength / this.averageFieldLength[field])) + tf)
score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (fieldLength / this.averageFieldLength[fieldName])) + tf)
score *= fieldBoost
score *= docBoost
scoreWithPrecision = Math.round(score * 1000) / 1000

@@ -303,3 +346,3 @@ // Converts 1.23456789 to 1.234.

tokenSet: this.tokenSet,
fields: this._fields,
fields: Object.keys(this._fields),
pipeline: this.searchPipeline

@@ -306,0 +349,0 @@ })

@@ -92,3 +92,4 @@ /*!

* Results will be returned sorted by their score, the most relevant results
* will be returned first.
* will be returned first. For details on how the score is calculated, please see
* the {@link https://lunrjs.com/guides/searching.html#scoring|guide}.
*

@@ -278,3 +279,3 @@ * For more programmatic querying use lunr.Index#query.

*/
queryVectors[field].upsert(termIndex, 1 * clause.boost, function (a, b) { return a + b })
queryVectors[field].upsert(termIndex, clause.boost, function (a, b) { return a + b })

@@ -281,0 +282,0 @@ /**

@@ -178,3 +178,3 @@ /**

if (Array.isArray(term)) {
term.forEach(function (t) { this.term(t, options) }, this)
term.forEach(function (t) { this.term(t, lunr.utils.clone(options)) }, this)
return this

@@ -181,0 +181,0 @@ }

@@ -164,4 +164,3 @@ /*!

/**
* Calculates the cosine similarity between this vector and another
* vector.
* Calculates the similarity between this vector and another vector.
*

@@ -173,3 +172,3 @@ * @param {lunr.Vector} otherVector - The other vector to calculate the

lunr.Vector.prototype.similarity = function (otherVector) {
return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude()) || 0
return this.dot(otherVector) / this.magnitude() || 0
}

@@ -176,0 +175,0 @@

{
"name": "lunr",
"description": "Simple full-text search in your browser.",
"version": "2.2.1",
"version": "2.3.0",
"author": "Oliver Nightingale",

@@ -21,6 +21,6 @@ "keywords": ["search"],

"jsdoc": "3.5.x",
"mocha": "3.0.x",
"mocha": "3.3.x",
"mustache": "2.2.x",
"node-static": "0.7.x",
"uglify-js": "2.4.x",
"uglify-js": "2.6.x",
"word-list": "1.0.x"

@@ -27,0 +27,0 @@ },

@@ -53,2 +53,19 @@ suite('lunr.Builder', function () {

})
test('extracting nested properties from a document', function () {
var extractor = function (d) { return d.person.name }
this.builder.field('name', {
extractor: extractor
})
this.builder.add({
id: 'id',
person: {
name: 'bob'
}
})
assert.deepProperty(this.builder.invertedIndex, 'bob.name.id')
})
})

@@ -60,4 +77,11 @@

builder.field('foo')
assert.include(builder._fields, 'foo')
assert.property(builder._fields, 'foo')
})
test('field with illegal characters', function () {
var builder = new lunr.Builder
assert.throws(function () {
builder.field('foo/bar')
})
})
})

@@ -64,0 +88,0 @@

@@ -52,2 +52,13 @@ suite('lunr.Query', function () {

suite('multiple string terms with options', function () {
setup(function () {
this.query.term(['foo', 'bar'], { usePipeline: false })
})
test('clause has the correct term', function () {
var terms = this.query.clauses.map(function (c) { return c.term })
assert.sameMembers(terms, ['foo', 'bar'])
})
})
suite('multiple token terms', function () {

@@ -54,0 +65,0 @@ setup(function () {

suite('search', function () {
setup(function () {
var documents = [{
this.documents = [{
id: 'a',

@@ -19,33 +19,29 @@ title: 'Mr. Green kills Colonel Mustard',

}]
})
this.idx = lunr(function () {
this.ref('id')
this.field('title')
this.field('body')
suite('with build-time field boosts', function () {
setup(function () {
var self = this
documents.forEach(function (document) {
this.add(document)
}, this)
this.idx = lunr(function () {
this.ref('id')
this.field('title')
this.field('body', { boost: 10 })
self.documents.forEach(function (document) {
this.add(document)
}, this)
})
})
})
suite('single term search', function () {
suite('one match', function () {
suite('no query boosts', function () {
var assertions = function () {
test('one result returned', function () {
assert.lengthOf(this.results, 1)
test('document b ranks highest', function () {
assert.equal('b', this.results[0].ref)
})
test('document c matches', function () {
assert.equal('c', this.results[0].ref)
})
test('matching term', function () {
assert.sameMembers(['scarlett'], Object.keys(this.results[0].matchData.metadata))
})
}
suite('#seach', function () {
suite('#search', function () {
setup(function () {
this.results = this.idx.search('scarlett')
this.results = this.idx.search('professor')
})

@@ -59,3 +55,3 @@

this.results = this.idx.query(function (q) {
q.term('scarlett')
q.term('professor')
})

@@ -67,59 +63,70 @@ })

})
})
suite('no match', function () {
setup(function () {
this.results = this.idx.search('foo')
})
suite('with build-time document boost', function () {
setup(function () {
var self = this
test('no matches', function () {
assert.lengthOf(this.results, 0)
this.idx = lunr(function () {
this.ref('id')
this.field('title')
this.field('body')
self.documents.forEach(function (document) {
var boost = document.id == 'c' ? 10 : 1
this.add(document, { boost: boost })
}, this)
})
})
suite('multiple matches', function () {
setup(function () {
this.results = this.idx.search('plant')
})
suite('no query boost', function () {
var assertions = function () {
test('document c ranks highest', function () {
assert.equal('c', this.results[0].ref)
})
}
test('has two matches', function () {
assert.lengthOf(this.results, 2)
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('plumb')
})
test('sorted by relevance', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
assertions()
})
})
suite('pipeline processing', function () {
// study would be stemmed to studi, tokens
// are stemmed by default on index and must
// also be stemmed on search to match
suite('enabled (default)', function () {
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.clause({term: 'study', usePipeline: true})
q.term('plumb')
})
})
test('has two matches', function () {
assert.lengthOf(this.results, 2)
})
assertions()
})
})
test('sorted by relevance', function () {
suite('with query boost', function () {
var assertions = function () {
test('document b ranks highest', function () {
assert.equal('b', this.results[0].ref)
assert.equal('a', this.results[1].ref)
})
}
suite('#search', function () {
setup(function () {
this.results = this.idx.search('green study^10')
})
assertions()
})
suite('disabled', function () {
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.clause({term: 'study', usePipeline: false})
q.term('green')
q.term('study', { boost: 10 })
})
})
test('no matches', function () {
assert.lengthOf(this.results, 0)
})
assertions()
})

@@ -129,136 +136,301 @@ })

suite('multiple terms', function () {
suite('all terms match', function () {
setup(function () {
this.results = this.idx.search('fellow candlestick')
})
suite('without build-time boosts', function () {
setup(function () {
var self = this
test('has one match', function () {
assert.lengthOf(this.results, 1)
})
this.idx = lunr(function () {
this.ref('id')
this.field('title')
this.field('body')
test('correct document returned', function () {
assert.equal('a', this.results[0].ref)
self.documents.forEach(function (document) {
this.add(document)
}, this)
})
test('matched terms returned', function () {
assert.sameMembers(['fellow', 'candlestick'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['body'], Object.keys(this.results[0].matchData.metadata['fellow']));
assert.sameMembers(['body'], Object.keys(this.results[0].matchData.metadata['candlestick']));
})
})
suite('one term matches', function () {
setup(function () {
this.results = this.idx.search('week foo')
})
suite('single term search', function () {
suite('one match', function () {
var assertions = function () {
test('one result returned', function () {
assert.lengthOf(this.results, 1)
})
test('has one match', function () {
assert.lengthOf(this.results, 1)
})
test('document c matches', function () {
assert.equal('c', this.results[0].ref)
})
test('correct document returned', function () {
assert.equal('c', this.results[0].ref)
})
test('matching term', function () {
assert.sameMembers(['scarlett'], Object.keys(this.results[0].matchData.metadata))
})
}
test('only matching terms returned', function () {
assert.sameMembers(['week'], Object.keys(this.results[0].matchData.metadata))
})
})
suite('#seach', function () {
setup(function () {
this.results = this.idx.search('scarlett')
})
suite('duplicate query terms', function () {
// https://github.com/olivernn/lunr.js/issues/256
// previously this would throw a duplicate index error
// because the query vector already contained an entry
// for the term 'fellow'
test('no errors', function () {
var idx = this.idx
assert.doesNotThrow(function () {
idx.search('fellow candlestick foo bar green plant fellow')
assertions()
})
})
})
suite('documents with all terms score higher', function () {
setup(function () {
this.results = this.idx.search('candlestick green')
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('scarlett')
})
})
test('has three matches', function () {
assert.lengthOf(this.results, 3)
assertions()
})
})
test('correct documents returned', function () {
var matchingDocuments = this.results.map(function (r) {
return r.ref
suite('no match', function () {
setup(function () {
this.results = this.idx.search('foo')
})
assert.sameMembers(['a', 'b', 'c'], matchingDocuments)
})
test('documents with all terms score highest', function () {
assert.equal('a', this.results[0].ref)
test('no matches', function () {
assert.lengthOf(this.results, 0)
})
})
test('matching terms are returned', function () {
assert.sameMembers(['candlestick', 'green'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['green'], Object.keys(this.results[1].matchData.metadata))
assert.sameMembers(['green'], Object.keys(this.results[2].matchData.metadata))
})
})
suite('multiple matches', function () {
setup(function () {
this.results = this.idx.search('plant')
})
suite('no terms match', function () {
setup(function () {
this.results = this.idx.search('foo bar')
test('has two matches', function () {
assert.lengthOf(this.results, 2)
})
test('sorted by relevance', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
})
test('no matches', function () {
assert.lengthOf(this.results, 0)
suite('pipeline processing', function () {
// study would be stemmed to studi, tokens
// are stemmed by default on index and must
// also be stemmed on search to match
suite('enabled (default)', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.clause({term: 'study', usePipeline: true})
})
})
test('has two matches', function () {
assert.lengthOf(this.results, 2)
})
test('sorted by relevance', function () {
assert.equal('b', this.results[0].ref)
assert.equal('a', this.results[1].ref)
})
})
suite('disabled', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.clause({term: 'study', usePipeline: false})
})
})
test('no matches', function () {
assert.lengthOf(this.results, 0)
})
})
})
})
suite('corpus terms are stemmed', function () {
setup(function () {
this.results = this.idx.search('water')
suite('multiple terms', function () {
suite('all terms match', function () {
setup(function () {
this.results = this.idx.search('fellow candlestick')
})
test('has one match', function () {
assert.lengthOf(this.results, 1)
})
test('correct document returned', function () {
assert.equal('a', this.results[0].ref)
})
test('matched terms returned', function () {
assert.sameMembers(['fellow', 'candlestick'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['body'], Object.keys(this.results[0].matchData.metadata['fellow']));
assert.sameMembers(['body'], Object.keys(this.results[0].matchData.metadata['candlestick']));
})
})
test('matches two documents', function () {
assert.lengthOf(this.results, 2)
suite('one term matches', function () {
setup(function () {
this.results = this.idx.search('week foo')
})
test('has one match', function () {
assert.lengthOf(this.results, 1)
})
test('correct document returned', function () {
assert.equal('c', this.results[0].ref)
})
test('only matching terms returned', function () {
assert.sameMembers(['week'], Object.keys(this.results[0].matchData.metadata))
})
})
test('matches correct documents', function () {
var matchingDocuments = this.results.map(function (r) {
return r.ref
suite('duplicate query terms', function () {
// https://github.com/olivernn/lunr.js/issues/256
// previously this would throw a duplicate index error
// because the query vector already contained an entry
// for the term 'fellow'
test('no errors', function () {
var idx = this.idx
assert.doesNotThrow(function () {
idx.search('fellow candlestick foo bar green plant fellow')
})
})
assert.sameMembers(['b', 'c'], matchingDocuments)
})
})
suite('field scoped terms', function () {
suite('only matches on scoped field', function () {
suite('documents with all terms score higher', function () {
setup(function () {
this.results = this.idx.search('title:plant')
this.results = this.idx.search('candlestick green')
})
test('one result returned', function () {
assert.lengthOf(this.results, 1)
test('has three matches', function () {
assert.lengthOf(this.results, 3)
})
test('returns the correct document', function () {
assert.equal('b', this.results[0].ref)
test('correct documents returned', function () {
var matchingDocuments = this.results.map(function (r) {
return r.ref
})
assert.sameMembers(['a', 'b', 'c'], matchingDocuments)
})
test('match data', function () {
assert.sameMembers(['plant'], Object.keys(this.results[0].matchData.metadata))
test('documents with all terms score highest', function () {
assert.equal('a', this.results[0].ref)
})
test('matching terms are returned', function () {
assert.sameMembers(['candlestick', 'green'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['green'], Object.keys(this.results[1].matchData.metadata))
assert.sameMembers(['green'], Object.keys(this.results[2].matchData.metadata))
})
})
suite('no matching terms', function () {
suite('no terms match', function () {
setup(function () {
this.results = this.idx.search('title:candlestick')
this.results = this.idx.search('foo bar')
})
test('no results returned', function () {
test('no matches', function () {
assert.lengthOf(this.results, 0)
})
})
suite('corpus terms are stemmed', function () {
setup(function () {
this.results = this.idx.search('water')
})
test('matches two documents', function () {
assert.lengthOf(this.results, 2)
})
test('matches correct documents', function () {
var matchingDocuments = this.results.map(function (r) {
return r.ref
})
assert.sameMembers(['b', 'c'], matchingDocuments)
})
})
suite('field scoped terms', function () {
suite('only matches on scoped field', function () {
setup(function () {
this.results = this.idx.search('title:plant')
})
test('one result returned', function () {
assert.lengthOf(this.results, 1)
})
test('returns the correct document', function () {
assert.equal('b', this.results[0].ref)
})
test('match data', function () {
assert.sameMembers(['plant'], Object.keys(this.results[0].matchData.metadata))
})
})
suite('no matching terms', function () {
setup(function () {
this.results = this.idx.search('title:candlestick')
})
test('no results returned', function () {
assert.lengthOf(this.results, 0)
})
})
})
suite('wildcard matching', function () {
suite('trailing wildcard', function () {
suite('no matches', function () {
setup(function () {
this.results = this.idx.search('fo*')
})
test('no results returned', function () {
assert.lengthOf(this.results, 0)
})
})
suite('one match', function () {
setup(function () {
this.results = this.idx.search('candle*')
})
test('one result returned', function () {
assert.lengthOf(this.results, 1)
})
test('correct document matched', function () {
assert.equal('a', this.results[0].ref)
})
test('matching terms returned', function () {
assert.sameMembers(['candlestick'], Object.keys(this.results[0].matchData.metadata))
})
})
suite('multiple terms match', function () {
setup(function () {
this.results = this.idx.search('pl*')
})
test('two results returned', function () {
assert.lengthOf(this.results, 2)
})
test('correct documents matched', function () {
var matchingDocuments = this.results.map(function (r) {
return r.ref
})
assert.sameMembers(['b', 'c'], matchingDocuments)
})
test('matching terms returned', function () {
assert.sameMembers(['plumb', 'plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plumb', 'plant'], Object.keys(this.results[1].matchData.metadata))
})
})
})
})
})

@@ -268,3 +440,3 @@

suite('trailing wildcard', function () {
suite('no matches', function () {
suite('no matches found', function () {
setup(function () {

@@ -279,50 +451,92 @@ this.results = this.idx.search('fo*')

suite('one match', function () {
suite('results found', function () {
setup(function () {
this.results = this.idx.search('candle*')
this.results = this.idx.search('pl*')
})
test('one result returned', function () {
assert.lengthOf(this.results, 1)
test('two results returned', function () {
assert.lengthOf(this.results, 2)
})
test('correct document matched', function () {
assert.equal('a', this.results[0].ref)
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
test('matching terms returned', function () {
assert.sameMembers(['candlestick'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plant', 'plumb'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plant', 'plumb'], Object.keys(this.results[1].matchData.metadata))
})
})
})
suite('multiple terms match', function () {
suite('leading wildcard', function () {
suite('no results found', function () {
setup(function () {
this.results = this.idx.search('pl*')
this.results = this.idx.search('*oo')
})
test('two results returned', function () {
test('no results found', function () {
assert.lengthOf(this.results, 0)
})
})
suite('results found', function () {
setup(function () {
this.results = this.idx.search('*ant')
})
test('two results found', function () {
assert.lengthOf(this.results, 2)
})
test('correct documents matched', function () {
var matchingDocuments = this.results.map(function (r) {
return r.ref
})
assert.sameMembers(['b', 'c'], matchingDocuments)
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
test('matching terms returned', function () {
assert.sameMembers(['plumb', 'plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plumb', 'plant'], Object.keys(this.results[1].matchData.metadata))
assert.sameMembers(['plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plant'], Object.keys(this.results[1].matchData.metadata))
})
})
})
suite('contained wildcard', function () {
suite('no results found', function () {
setup(function () {
this.results = this.idx.search('f*o')
})
test('no results found', function () {
assert.lengthOf(this.results, 0)
})
})
suite('results found', function () {
setup(function () {
this.results = this.idx.search('pl*nt')
})
test('two results found', function () {
assert.lengthOf(this.results, 2)
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
test('matching terms returned', function () {
assert.sameMembers(['plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plant'], Object.keys(this.results[1].matchData.metadata))
})
})
})
})
})
suite('wildcard matching', function () {
suite('trailing wildcard', function () {
suite('no matches found', function () {
suite('edit distance', function () {
suite('no results found', function () {
setup(function () {
this.results = this.idx.search('fo*')
this.results = this.idx.search('foo~1')
})

@@ -337,6 +551,6 @@

setup(function () {
this.results = this.idx.search('pl*')
this.results = this.idx.search('plont~1')
})
test('two results returned', function () {
test('two results found', function () {
assert.lengthOf(this.results, 2)

@@ -351,4 +565,4 @@ })

test('matching terms returned', function () {
assert.sameMembers(['plant', 'plumb'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plant', 'plumb'], Object.keys(this.results[1].matchData.metadata))
assert.sameMembers(['plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plant'], Object.keys(this.results[1].matchData.metadata))
})

@@ -358,6 +572,14 @@ })

suite('leading wildcard', function () {
suite('searching by field', function () {
suite('unknown field', function () {
test('throws lunr.QueryParseError', function () {
assert.throws(function () {
this.idx.search('unknown-field:plant')
}.bind(this), lunr.QueryParseError)
})
})
suite('no results found', function () {
setup(function () {
this.results = this.idx.search('*oo')
this.results = this.idx.search('title:candlestick')
})

@@ -372,7 +594,7 @@

setup(function () {
this.results = this.idx.search('*ant')
this.results = this.idx.search('title:plant')
})
test('two results found', function () {
assert.lengthOf(this.results, 2)
test('one results found', function () {
assert.lengthOf(this.results, 1)
})

@@ -382,3 +604,2 @@

assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})

@@ -388,3 +609,2 @@

assert.sameMembers(['plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plant'], Object.keys(this.results[1].matchData.metadata))
})

@@ -394,6 +614,6 @@ })

suite('contained wildcard', function () {
suite('term boosts', function () {
suite('no results found', function () {
setup(function () {
this.results = this.idx.search('f*o')
this.results = this.idx.search('foo^10')
})

@@ -408,3 +628,3 @@

setup(function () {
this.results = this.idx.search('pl*nt')
this.results = this.idx.search('scarlett candlestick^5')
})

@@ -417,3 +637,3 @@

test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
assert.equal('a', this.results[0].ref)
assert.equal('c', this.results[1].ref)

@@ -423,442 +643,410 @@ })

test('matching terms returned', function () {
assert.sameMembers(['plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plant'], Object.keys(this.results[1].matchData.metadata))
assert.sameMembers(['candlestick'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['scarlett'], Object.keys(this.results[1].matchData.metadata))
})
})
})
})
suite('edit distance', function () {
suite('no results found', function () {
setup(function () {
this.results = this.idx.search('foo~1')
})
suite('typeahead style search', function () {
suite('no results found', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term("xyz", { boost: 100, usePipeline: true })
q.term("xyz", { boost: 10, usePipeline: false, wildcard: lunr.Query.wildcard.TRAILING })
q.term("xyz", { boost: 1, editDistance: 1 })
})
})
test('no results returned', function () {
assert.lengthOf(this.results, 0)
test('no results found', function () {
assert.lengthOf(this.results, 0)
})
})
})
suite('results found', function () {
setup(function () {
this.results = this.idx.search('plont~1')
})
suite('results found', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term("pl", { boost: 100, usePipeline: true })
q.term("pl", { boost: 10, usePipeline: false, wildcard: lunr.Query.wildcard.TRAILING })
q.term("pl", { boost: 1, editDistance: 1 })
})
})
test('two results found', function () {
assert.lengthOf(this.results, 2)
})
test('two results found', function () {
assert.lengthOf(this.results, 2)
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
test('matching terms returned', function () {
assert.sameMembers(['plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plant'], Object.keys(this.results[1].matchData.metadata))
test('matching terms returned', function () {
assert.sameMembers(['plumb', 'plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plumb', 'plant'], Object.keys(this.results[1].matchData.metadata))
})
})
})
})
suite('searching by field', function () {
suite('unknown field', function () {
test('throws lunr.QueryParseError', function () {
assert.throws(function () {
this.idx.search('unknown-field:plant')
}.bind(this), lunr.QueryParseError)
})
})
suite('term presence', function () {
suite('prohibited', function () {
suite('match', function () {
var assertions = function () {
test('two results found', function () {
assert.lengthOf(this.results, 2)
})
suite('no results found', function () {
setup(function () {
this.results = this.idx.search('title:candlestick')
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
test('no results found', function () {
assert.lengthOf(this.results, 0)
})
})
test('matching terms returned', function () {
assert.sameMembers(['green'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['green'], Object.keys(this.results[1].matchData.metadata))
})
}
suite('results found', function () {
setup(function () {
this.results = this.idx.search('title:plant')
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('candlestick', { presence: lunr.Query.presence.PROHIBITED })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
})
})
test('one results found', function () {
assert.lengthOf(this.results, 1)
})
assertions()
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('-candlestick green')
})
test('matching terms returned', function () {
assert.sameMembers(['plant'], Object.keys(this.results[0].matchData.metadata))
})
})
})
assertions()
})
})
suite('term boosts', function () {
suite('no results found', function () {
setup(function () {
this.results = this.idx.search('foo^10')
})
suite('no match', function () {
var assertions = function () {
test('no matches', function () {
assert.lengthOf(this.results, 0)
})
}
test('no results found', function () {
assert.lengthOf(this.results, 0)
})
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('green', { presence: lunr.Query.presence.PROHIBITED })
})
})
suite('results found', function () {
setup(function () {
this.results = this.idx.search('scarlett candlestick^5')
})
assertions()
})
test('two results found', function () {
assert.lengthOf(this.results, 2)
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('-green')
})
test('matching documents returned', function () {
assert.equal('a', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
test('matching terms returned', function () {
assert.sameMembers(['candlestick'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['scarlett'], Object.keys(this.results[1].matchData.metadata))
})
})
})
suite('typeahead style search', function () {
suite('no results found', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term("xyz", { boost: 100, usePipeline: true })
q.term("xyz", { boost: 10, usePipeline: false, wildcard: lunr.Query.wildcard.TRAILING })
q.term("xyz", { boost: 1, editDistance: 1 })
assertions()
})
})
})
test('no results found', function () {
assert.lengthOf(this.results, 0)
})
})
suite('negated query no match', function () {
var assertions = function () {
test('all documents returned', function () {
assert.lengthOf(this.results, 3)
})
suite('results found', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term("pl", { boost: 100, usePipeline: true })
q.term("pl", { boost: 10, usePipeline: false, wildcard: lunr.Query.wildcard.TRAILING })
q.term("pl", { boost: 1, editDistance: 1 })
})
})
test('all results have same score', function () {
assert.isTrue(this.results.every(function (r) { return r.score === 0 }))
})
}
test('two results found', function () {
assert.lengthOf(this.results, 2)
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('qwertyuiop', { presence: lunr.Query.presence.PROHIBITED })
})
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
assertions()
})
test('matching terms returned', function () {
assert.sameMembers(['plumb', 'plant'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['plumb', 'plant'], Object.keys(this.results[1].matchData.metadata))
})
})
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search("-qwertyuiop")
})
suite('term presence', function () {
suite('prohibited', function () {
suite('match', function () {
var assertions = function () {
test('two results found', function () {
assert.lengthOf(this.results, 2)
assertions()
})
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
assert.equal('c', this.results[1].ref)
})
suite('negated query some match', function () {
var assertions = function () {
test('all documents returned', function () {
assert.lengthOf(this.results, 1)
})
test('matching terms returned', function () {
assert.sameMembers(['green'], Object.keys(this.results[0].matchData.metadata))
assert.sameMembers(['green'], Object.keys(this.results[1].matchData.metadata))
})
}
test('all results have same score', function () {
assert.isTrue(this.results.every(function (r) { return r.score === 0 }))
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('candlestick', { presence: lunr.Query.presence.PROHIBITED })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
test('matching documents returned', function () {
assert.equal('a', this.results[0].ref)
})
})
}
assertions()
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { presence: lunr.Query.presence.PROHIBITED })
})
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('-candlestick green')
assertions()
})
assertions()
})
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search("-plant")
})
suite('no match', function () {
var assertions = function () {
test('no matches', function () {
assert.lengthOf(this.results, 0)
assertions()
})
}
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('green', { presence: lunr.Query.presence.PROHIBITED })
suite('field match', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
})
})
assertions()
})
test('matching documents returned', function () {
assert.equal('c', this.results[0].ref)
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('-green')
})
test('matching terms returned', function () {
assert.sameMembers(['plumb'], Object.keys(this.results[0].matchData.metadata))
})
}
assertions()
})
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { presence: lunr.Query.presence.PROHIBITED, fields: ['title'] })
q.term('plumb', { presence: lunr.Query.presence.OPTIONAL })
})
})
suite('negated query no match', function () {
var assertions = function () {
test('all documents returned', function () {
assert.lengthOf(this.results, 3)
assertions()
})
test('all results have same score', function () {
assert.isTrue(this.results.every(function (r) { return r.score === 0 }))
})
}
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('qwertyuiop', { presence: lunr.Query.presence.PROHIBITED })
suite('#search', function () {
setup(function () {
this.results = this.idx.search('-title:plant plumb')
})
})
assertions()
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search("-qwertyuiop")
assertions()
})
assertions()
})
})
suite('negated query some match', function () {
var assertions = function () {
test('all documents returned', function () {
assert.lengthOf(this.results, 1)
})
suite('required', function () {
suite('match', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
})
test('all results have same score', function () {
assert.isTrue(this.results.every(function (r) { return r.score === 0 }))
})
test('matching documents returned', function () {
assert.equal('a', this.results[0].ref)
})
test('matching documents returned', function () {
assert.equal('a', this.results[0].ref)
})
}
test('matching terms returned', function () {
assert.sameMembers(['candlestick', 'green'], Object.keys(this.results[0].matchData.metadata))
})
}
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { presence: lunr.Query.presence.PROHIBITED })
suite('#search', function () {
setup(function () {
this.results = this.idx.search("+candlestick green")
})
assertions()
})
assertions()
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('candlestick', { presence: lunr.Query.presence.REQUIRED })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
})
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search("-plant")
assertions()
})
assertions()
})
})
suite('field match', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
})
suite('no match', function () {
var assertions = function () {
test('no matches', function () {
assert.lengthOf(this.results, 0)
})
}
test('matching documents returned', function () {
assert.equal('c', this.results[0].ref)
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('mustard', { presence: lunr.Query.presence.REQUIRED })
q.term('plant', { presence: lunr.Query.presence.REQUIRED })
})
})
test('matching terms returned', function () {
assert.sameMembers(['plumb'], Object.keys(this.results[0].matchData.metadata))
assertions()
})
}
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { presence: lunr.Query.presence.PROHIBITED, fields: ['title'] })
q.term('plumb', { presence: lunr.Query.presence.OPTIONAL })
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+mustard +plant')
})
assertions()
})
assertions()
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('-title:plant plumb')
})
suite('no matching term', function () {
var assertions = function () {
test('no matches', function () {
assert.lengthOf(this.results, 0)
})
}
assertions()
})
})
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('qwertyuiop', { presence: lunr.Query.presence.REQUIRED })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
})
})
suite('required', function () {
suite('match', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
assertions()
})
test('matching documents returned', function () {
assert.equal('a', this.results[0].ref)
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+qwertyuiop green')
})
test('matching terms returned', function () {
assert.sameMembers(['candlestick', 'green'], Object.keys(this.results[0].matchData.metadata))
assertions()
})
}
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search("+candlestick green")
})
suite('field match', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
})
assertions()
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('candlestick', { presence: lunr.Query.presence.REQUIRED })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
test('matching terms returned', function () {
assert.sameMembers(['plant', 'green'], Object.keys(this.results[0].matchData.metadata))
})
})
}
assertions()
})
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { presence: lunr.Query.presence.REQUIRED, fields: ['title'] })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
})
})
suite('no match', function () {
var assertions = function () {
test('no matches', function () {
assert.lengthOf(this.results, 0)
assertions()
})
}
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('mustard', { presence: lunr.Query.presence.REQUIRED })
q.term('plant', { presence: lunr.Query.presence.REQUIRED })
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+title:plant green')
})
assertions()
})
assertions()
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+mustard +plant')
})
suite('field and non field match', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
})
assertions()
})
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
})
suite('no matching term', function () {
var assertions = function () {
test('no matches', function () {
assert.lengthOf(this.results, 0)
})
}
test('matching terms returned', function () {
assert.sameMembers(['plant', 'green'], Object.keys(this.results[0].matchData.metadata))
})
}
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('qwertyuiop', { presence: lunr.Query.presence.REQUIRED })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+title:plant +green')
})
assertions()
})
assertions()
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { fields: ['title'], presence: lunr.Query.presence.REQUIRED })
q.term('green', { presence: lunr.Query.presence.REQUIRED })
})
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+qwertyuiop green')
assertions()
})
assertions()
})
})
suite('field match', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
})
suite('different fields', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
})
test('matching terms returned', function () {
assert.sameMembers(['plant', 'green'], Object.keys(this.results[0].matchData.metadata))
})
}
test('matching terms returned', function () {
assert.sameMembers(['studi', 'plant'], Object.keys(this.results[0].matchData.metadata))
})
}
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { presence: lunr.Query.presence.REQUIRED, fields: ['title'] })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+title:plant +body:study')
})
assertions()
})
assertions()
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { fields: ['title'], presence: lunr.Query.presence.REQUIRED })
q.term('study', { fields: ['body'], presence: lunr.Query.presence.REQUIRED })
})
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+title:plant green')
assertions()
})
assertions()
})
})
suite('field and non field match', function () {
suite('combined', function () {
var assertions = function () {

@@ -878,15 +1066,8 @@ test('one result found', function () {

suite('#search', function () {
setup(function () {
this.results = this.idx.search('+title:plant +green')
})
assertions()
})
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { fields: ['title'], presence: lunr.Query.presence.REQUIRED })
q.term('green', { presence: lunr.Query.presence.REQUIRED })
q.term('plant', { presence: lunr.Query.presence.REQUIRED })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
q.term('office', { presence: lunr.Query.presence.PROHIBITED })
})

@@ -897,22 +1078,6 @@ })

})
})
suite('different fields', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
})
test('matching terms returned', function () {
assert.sameMembers(['studi', 'plant'], Object.keys(this.results[0].matchData.metadata))
})
}
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+title:plant +body:study')
this.results = this.idx.search('+plant green -office')
})

@@ -923,52 +1088,5 @@

suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { fields: ['title'], presence: lunr.Query.presence.REQUIRED })
q.term('study', { fields: ['body'], presence: lunr.Query.presence.REQUIRED })
})
})
assertions()
})
})
})
suite('combined', function () {
var assertions = function () {
test('one result found', function () {
assert.lengthOf(this.results, 1)
})
test('matching documents returned', function () {
assert.equal('b', this.results[0].ref)
})
test('matching terms returned', function () {
assert.sameMembers(['plant', 'green'], Object.keys(this.results[0].matchData.metadata))
})
}
suite('#query', function () {
setup(function () {
this.results = this.idx.query(function (q) {
q.term('plant', { presence: lunr.Query.presence.REQUIRED })
q.term('green', { presence: lunr.Query.presence.OPTIONAL })
q.term('office', { presence: lunr.Query.presence.PROHIBITED })
})
})
assertions()
})
suite('#search', function () {
setup(function () {
this.results = this.idx.search('+plant green -office')
})
assertions()
})
})
})
})

@@ -34,3 +34,3 @@ suite('lunr.Vector', function () {

assert.approximately(v1.similarity(v2), 0.111, 0.001)
assert.approximately(v1.similarity(v2), 0.5, 0.01)
})

@@ -37,0 +37,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc