search.js 5.81 KiB
import lunr from "lunr";
import searchData from "@/assets/data/search-data.json";
import searchIndexData from "@/assets/data/search-index.json";
import { registerAcronymAliases } from "@/plugins/search/lunr-pipelines";
/**
* Search api. Provides search and context capabilities.
* @example
* import Search from "@/api/search";
* const searchApi = new Search();
* const results = searchApi.search("cnap");
* console.debug("search results:", results);
* console.debug("search context of first result:", searchApi.getContext(results[0]));
*/
export default class Search {
constructor() {
// reconstitute the search index in memory
registerAcronymAliases();
this.index = lunr.Index.load(searchIndexData);
// hash the context data by id (page path) for faster lookups over array
this.contextData = searchData.reduce((all, data) => {
all[data.id] = data;
return all;
}, {});
}
/**
* Performs a search on the search index. See https://lunrjs.com/guides/searching.html
* @param {String} query the string to search on
* @returns {Array[Object]} search results, including match position metadata
* @example
* [{
* "ref": "/resources",
* "score": 1.21,
* "matchData": {
* "metadata": {
* "cloud native access point": {
* "content": {
* "position": [
* [
* 42,
* 4
* ]
* ]
* }
* }
* }
* }
* }]
*/
search(query) {
return this.index.search(query);
}
_getContextForPosition(matchValueField, dataMatchField, surroundChars) {
const contextData = [];
// translate lunrjs match position indexes to actual characters
for (const position of matchValueField.position) {
const matchStart = position[0];
const matchEnd = matchStart + position[1];
const contextStart = Math.max(0, matchStart - surroundChars);
const contextEnd = Math.min(
dataMatchField.length,
matchEnd + surroundChars
);
contextData.push({
match: dataMatchField.substring(matchStart, matchEnd),
context: dataMatchField.substring(contextStart, contextEnd),
});
}