From 03e59eaf23ae994eb9ff50c2a5b4341ce51acfe6 Mon Sep 17 00:00:00 2001 From: Robert Buels Date: Tue, 1 Aug 2023 23:39:29 +0000 Subject: [PATCH] make text indexing paths configurable, index definitions by default --- .../OntologyManager/OntologyStore/fulltext.ts | 14 ++++++++++---- .../OntologyStore/indexeddb-storage.ts | 2 +- .../src/OntologyManager/index.ts | 18 ++++++++++++++++-- .../src/components/OntologyTermMultiSelect.tsx | 1 + packages/jbrowse-plugin-apollo/src/session.ts | 7 +++++-- 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/fulltext.ts b/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/fulltext.ts index 1c65918df..d0c7cf670 100644 --- a/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/fulltext.ts +++ b/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/fulltext.ts @@ -8,7 +8,11 @@ import { OntologyTerm } from '..' function getStringAt(obj: Record, path: string[]) { let thing = obj for (const key of path) { - thing = thing[key] as Record + if (key in thing) { + thing = thing[key] as Record + } else { + return + } } return String(thing) } @@ -29,9 +33,11 @@ export function getWords(node: OntologyDBNode, paths: string[][]) { const wordSet = new Set() for (const path of paths) { const text = getStringAt(node, path) - stringToWords(text).forEach((word) => { - wordSet.add(word) - }) + if (text) { + stringToWords(text).forEach((word) => { + wordSet.add(word) + }) + } } return wordSet } diff --git a/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/indexeddb-storage.ts b/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/indexeddb-storage.ts index 5c068e677..473567978 100644 --- a/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/indexeddb-storage.ts +++ b/packages/jbrowse-plugin-apollo/src/OntologyManager/OntologyStore/indexeddb-storage.ts @@ -96,7 +96,7 @@ export async function loadOboGraphJson(this: OntologyStore, db: Database) { const nodeStore = tx.objectStore('nodes') const fullTextIndexPaths = this.options.textIndexing?.indexPaths ? this.options.textIndexing?.indexPaths.map((p) => p.split('/')) - : [['lbl']] + : [['lbl'], ['meta', 'definition', 'val']] for (const node of graph.nodes ?? []) { if (isOntologyDBNode(node)) { await nodeStore.add({ diff --git a/packages/jbrowse-plugin-apollo/src/OntologyManager/index.ts b/packages/jbrowse-plugin-apollo/src/OntologyManager/index.ts index 63d38363f..5d41d7de0 100644 --- a/packages/jbrowse-plugin-apollo/src/OntologyManager/index.ts +++ b/packages/jbrowse-plugin-apollo/src/OntologyManager/index.ts @@ -7,7 +7,7 @@ import { import { autorun } from 'mobx' import { Instance, addDisposer, getSnapshot, types } from 'mobx-state-tree' -import OntologyStore from './OntologyStore' +import OntologyStore, { OntologyStoreOptions } from './OntologyStore' import { OntologyDBNode } from './OntologyStore/indexeddb-schema' export { isDeprecated } from './OntologyStore/indexeddb-schema' @@ -17,6 +17,7 @@ export const OntologyRecordType = types name: types.string, version: 'unversioned', source: types.union(LocalPathLocation, UriLocation, BlobLocation), + options: types.frozen(), }) .volatile((_self) => ({ dataStore: undefined as undefined | OntologyStore, @@ -31,6 +32,7 @@ export const OntologyRecordType = types self.name, self.version, getSnapshot(self.source), + self.options, ) }, afterCreate() { @@ -104,8 +106,14 @@ export const OntologyManagerType = types name: string, version: string, source: Instance | Instance, + options?: OntologyStoreOptions, ) { - const newlen = self.ontologies.push({ name, version, source }) + const newlen = self.ontologies.push({ + name, + version, + source, + options: options ?? {}, + }) // access it immediately to fire its lifecycle hooks // (see https://github.com/mobxjs/mobx-state-tree/issues/1665) self.ontologies[newlen - 1].ping() @@ -140,6 +148,12 @@ export const OntologyRecordConfiguration = ConfigurationSchema( uri: 'http://example.com/myontology.json', }, }, + textIndexingPaths: { + type: 'frozen', + description: + 'JSON paths for text fields that will be indexed for text searching', + defaultValue: ['lbl', 'meta/definition/val'], + }, }, ) diff --git a/packages/jbrowse-plugin-apollo/src/components/OntologyTermMultiSelect.tsx b/packages/jbrowse-plugin-apollo/src/components/OntologyTermMultiSelect.tsx index 2ef18a568..ccf124b59 100644 --- a/packages/jbrowse-plugin-apollo/src/components/OntologyTermMultiSelect.tsx +++ b/packages/jbrowse-plugin-apollo/src/components/OntologyTermMultiSelect.tsx @@ -208,6 +208,7 @@ export function OntologyTermMultiSelect({ const label = option.lbl ?? '(no label)' const matches = highlightMatch(label, inputValue, { insideWords: true, + findAllOccurrences: true, }) parts = highlightParse(label, matches) return ( diff --git a/packages/jbrowse-plugin-apollo/src/session.ts b/packages/jbrowse-plugin-apollo/src/session.ts index b4c985d8e..bf1f6b051 100644 --- a/packages/jbrowse-plugin-apollo/src/session.ts +++ b/packages/jbrowse-plugin-apollo/src/session.ts @@ -219,15 +219,18 @@ function clientDataStoreFactory( >[] for (const ont of configuredOntologies || []) { - const [name, version, source] = [ + const [name, version, source, indexPaths] = [ readConfObject(ont, 'name') as string, readConfObject(ont, 'version') as string, readConfObject(ont, 'source') as | Instance | Instance, + readConfObject(ont, 'textIndexingPaths') as string[], ] if (!ontologyManager.findOntology(name)) { - ontologyManager.addOntology(name, version, source) + ontologyManager.addOntology(name, version, source, { + textIndexing: { indexPaths }, + }) } }