Vue: Fulltext search your Vuex store with MiniSearch
Last modified Sep 16 2019 13:20 by Kees de Kooter
Adding full text search to an application and especially nifty features like autocomplete has always been a quite tedious job. The index had to be configured at the backend. APIs needed to be written. Performance was always a concern. Not to mention security.
Why not do all of this on the client side acting on the data the user has in his local store? A brilliant little library called MiniSearch by Luco Ongaro makes this possible.
Fulltext indexing in 6 lines of code!
// Initalize MiniSearch with a schema
const miniSearch = new MiniSearch({fields: ['type', 'title', 'subtitle', 'body']})
// Keep a copy of the indexed documents - we need this if we want to remove or update a document
let documents = new Map()
function indexDocument(document) {
// Remove first if it already exists
if (documents.get(document.id)) {
miniSearch.remove(documents.get(document.id)
}
miniSearch.add(document)
document.set(document.id, document)
}
function search(query) {
return miniSearch(query, {fuzzy: 1, combineWith: 'AND'})
.map(hit => documents.get(hit.id))
}
export { indexDocument }
Hook things up to your Vuex store
Vuex is extensible with plugins that can intercept events taking place in the store.
import { indexDocument } from './search'
export const searchPlugin = store => {
store.subscribe((mutation, state) => {
if (mutation.type === 'note') {
indexDocument(note)
}
})
}
And of course don't forget to let Vuex know to use this plugin:
import { searchPlugin } from './search-plugin'
export default new Vuex.Store({
...
plugins: [searchPlugin]
}
That's about it. From a searchbox in your application you can now call search and populate a search results list.