Disable fuzzy search

It doesn't work well for highly precise values, or small datasets, or prefixes.
Which are our three use cases.
This commit is contained in:
Michael Lange 2017-10-18 12:52:24 -07:00
parent 721905b628
commit 635263b8aa
4 changed files with 8 additions and 25 deletions

View file

@ -20,7 +20,7 @@ export default Controller.extend(Sortable, Searchable, {
sortProperty: 'modifyIndex',
sortDescending: true,
searchProps: computed(() => ['id', 'name']),
searchProps: computed(() => ['shortId', 'name']),
allocations: computed('model.allocations.[]', function() {
return this.get('model.allocations') || [];

View file

@ -18,7 +18,7 @@ export default Controller.extend(Sortable, Searchable, {
sortProperty: 'modifyIndex',
sortDescending: true,
searchProps: computed(() => ['id', 'name']),
searchProps: computed(() => ['shortId', 'name']),
listToSort: computed.alias('model.allocations'),
listToSearch: computed.alias('listSorted'),

View file

@ -14,8 +14,7 @@ const { Mixin, computed, get } = Ember;
- listToSearch: the list of objects to search
Properties provided:
- listSearched: a subset of listToSearch of items that meet the search criteria,
ordered by relevance.
- listSearched: a subset of listToSearch of items that meet the search criteria
*/
export default Mixin.create({
searchTerm: '',
@ -40,20 +39,16 @@ export default Mixin.create({
listSearched: computed('fuse', 'searchTerm', function() {
const { fuse, searchTerm } = this.getProperties('fuse', 'searchTerm');
if (searchTerm && searchTerm.length) {
if (searchTerm.startsWith('/')) {
return regexSearch(searchTerm, fuse);
}
return fuse.search(searchTerm);
return regexSearch(searchTerm, fuse);
}
return this.get('listToSearch');
}),
});
function regexSearch(term, { list, options: { keys } }) {
const regexStr = term.slice(1);
if (regexStr.length) {
if (term.length) {
try {
const regex = new RegExp(regexStr, 'i');
const regex = new RegExp(term, 'i');
// Test the value of each key for each object against the regex
// All that match are returned.
return list.filter(item => keys.some(key => regex.test(get(item, key))));

View file

@ -24,18 +24,6 @@ test('the searchable mixin does nothing when there is no search term', function(
assert.deepEqual(subject.get('listSearched'), subject.get('source'));
});
test('the searchable mixin allows for fuzzy match search', function(assert) {
const subject = this.subject();
subject.set('source', [{ id: '1', name: 'hello' }, { id: '2', name: 'world' }]);
subject.set('searchTerm', 'helo');
assert.deepEqual(
subject.get('listSearched'),
[{ id: '1', name: 'hello' }],
'hello matched for the term helo'
);
});
test('the searchable mixin allows for regex search', function(assert) {
const subject = this.subject();
subject.set('source', [
@ -44,7 +32,7 @@ test('the searchable mixin allows for regex search', function(assert) {
{ id: '3', name: 'oranges' },
]);
subject.set('searchTerm', '/.+l+[A-Z]$');
subject.set('searchTerm', '.+l+[A-Z]$');
assert.deepEqual(
subject.get('listSearched'),
[{ id: '1', name: 'hello' }, { id: '2', name: 'world' }],
@ -60,7 +48,7 @@ test('the searchable mixin only searches the declared search props', function(as
{ id: '3', name: 'Mexico', continent: 'North America' },
]);
subject.set('searchTerm', '/America');
subject.set('searchTerm', 'America');
assert.deepEqual(
subject.get('listSearched'),
[{ id: '1', name: 'United States of America', continent: 'North America' }],