UBERF-5018: search improvements/Indexing fix (#4403)

Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
Vyacheslav Tumanov 2024-01-23 20:26:15 +05:00 committed by GitHub
parent 27c428602a
commit 28dca6632c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 48 additions and 21 deletions

View File

@ -55,7 +55,9 @@ export function createModel (builder: Builder): void {
}
]
},
getSearchTitle: serverContact.function.ContactNameProvider
getSearchTitle: {
name: serverContact.function.ContactNameProvider
}
})
builder.createDoc(serverCore.class.Trigger, core.space.Model, {

View File

@ -45,8 +45,8 @@ export class TObjectDDParticipant extends TClass implements ObjectDDParticipant
@Mixin(serverCore.mixin.SearchPresenter, core.class.Class)
export class TSearchPresenter extends TClass implements SearchPresenter {
searchConfig!: ClassSearchConfig
getSearchShortTitle!: Resource<SearchPresenterFunc>
getSearchTitle!: Resource<SearchPresenterFunc>
getSearchShortTitle!: SearchPresenterFunc
getSearchTitle!: SearchPresenterFunc
}
export function createModel (builder: Builder): void {

View File

@ -65,10 +65,13 @@ export function createModel (builder: Builder): void {
props: ['number']
},
title: {
props: [{ _class: ['attachedTo', '_class'] }, { name: ['attachedTo', 'name'] }]
tmpl: '{name} - {vacName}',
props: [{ _class: ['attachedTo', '_class'] }, { name: ['attachedTo', 'name'] }, { vacName: ['space', 'name'] }]
}
},
getSearchTitle: serverContact.function.ContactNameProvider
getSearchTitle: {
name: serverContact.function.ContactNameProvider
}
})
builder.mixin(

View File

@ -16,7 +16,7 @@
import type { Plugin, Resource } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import type { TriggerFunc, SearchPresenterFunc } from '@hcengineering/server-core'
import type { TriggerFunc, SearchPresenterProvider } from '@hcengineering/server-core'
import { Presenter } from '@hcengineering/server-notification'
/**
@ -38,6 +38,6 @@ export default plugin(serverContactId, {
OrganizationHTMLPresenter: '' as Resource<Presenter>,
OrganizationTextPresenter: '' as Resource<Presenter>,
ContactNameProvider: '' as Resource<SearchPresenterFunc>
ContactNameProvider: '' as Resource<SearchPresenterProvider>
}
})

View File

@ -178,12 +178,12 @@ export class FullTextPushStage implements FullTextPipelineStage {
}
}
}
const parentDoc: DocIndexState | undefined = undefined
let parentDoc: DocIndexState | undefined
if (doc.attachedToClass != null && doc.attachedTo != null) {
const propagate: Ref<Class<Doc>>[] = collectPropagate(pipeline, doc.attachedToClass)
if (propagate.some((it) => pipeline.hierarchy.isDerived(doc.objectClass, it))) {
// We need to include all parent content into this one.
const [parentDoc] = await metrics.with(
;[parentDoc] = await metrics.with(
'find-parent',
{},
async (ctx) =>

View File

@ -107,4 +107,4 @@ export const fieldStateId = 'fld-v11'
/**
* @public
*/
export const fullTextPushStageId = 'fts-v9'
export const fullTextPushStageId = 'fts-v9bc'

View File

@ -1,8 +1,8 @@
import { Class, Doc, DocIndexState, docKey, Hierarchy, Ref, RefTo, SearchResultDoc } from '@hcengineering/core'
import { getResource } from '@hcengineering/platform'
import { getResource, Resource } from '@hcengineering/platform'
import plugin from './plugin'
import { ClassSearchConfigProps, IndexedDoc, SearchPresenter, SearchScoring } from './types'
import { ClassSearchConfigProps, IndexedDoc, SearchPresenter, SearchPresenterFunc, SearchScoring } from './types'
interface IndexedReader {
get: (attribute: string) => any
@ -39,7 +39,14 @@ function createIndexedReader (
}
}
function readAndMapProps (reader: IndexedReader, props: ClassSearchConfigProps[]): Record<string, any> {
async function readAndMapProps (
reader: IndexedReader,
props: ClassSearchConfigProps[],
searchProvider?: {
hierarchy: Hierarchy
providers: SearchPresenterFunc
}
): Promise<Record<string, any>> {
const res: Record<string, any> = {}
for (const prop of props) {
if (typeof prop === 'string') {
@ -48,7 +55,18 @@ function readAndMapProps (reader: IndexedReader, props: ClassSearchConfigProps[]
for (const [propName, rest] of Object.entries(prop)) {
if (rest.length > 1) {
const val = reader.getDoc(rest[0])?.get(rest[1])
res[propName] = Array.isArray(val) ? val[0] : val
const v = Array.isArray(val) ? val[0] : val
if (searchProvider !== undefined) {
const func =
searchProvider.providers !== undefined && Object.keys(searchProvider.providers).includes(propName)
? ((await getResource(searchProvider.providers[propName])) as any)
: undefined
if (func !== undefined) {
res[propName] = func(searchProvider.hierarchy, { _class: res?._class, [propName]: v })
continue
}
}
res[propName] = v
}
}
}
@ -116,16 +134,16 @@ export async function updateDocWithPresenter (
let value
if (prop.config.tmpl !== undefined) {
const tmpl = prop.config.tmpl
const renderProps = readAndMapProps(reader, prop.config.props)
const renderProps = await readAndMapProps(reader, prop.config.props, { hierarchy, providers: prop.provider })
value = fillTemplate(tmpl, renderProps)
} else if (typeof prop.config === 'string') {
value = reader.get(prop.config)
} else if (prop.provider !== undefined) {
const func = (await getResource(prop.provider)) as any
const renderProps = readAndMapProps(reader, prop.config.props)
const func = await getResource(Object.values(prop.provider)[0] as Resource<any>)
const renderProps = await readAndMapProps(reader, prop.config.props)
value = func(hierarchy, { _class: elasticDoc._class, ...renderProps })
} else if (prop.name === 'searchIcon') {
value = readAndMapProps(reader, prop.config.props)
value = await readAndMapProps(reader, prop.config.props)
}
elasticDoc[prop.name] = value
}

View File

@ -349,7 +349,11 @@ export type SearchProps = Record<string, string>
/**
* @public
*/
export type SearchPresenterFunc = (hierarchy: Hierarchy, props: SearchProps) => string
export type SearchPresenterProvider = (hierarchy: Hierarchy, props: SearchProps) => string
/**
* @public
*/
export type SearchPresenterFunc = Record<string, Resource<SearchPresenterProvider>>
/**
* @public
@ -386,6 +390,6 @@ export interface ClassSearchConfig {
*/
export interface SearchPresenter extends Class<Doc> {
searchConfig: ClassSearchConfig
getSearchShortTitle?: Resource<SearchPresenterFunc>
getSearchTitle?: Resource<SearchPresenterFunc>
getSearchShortTitle?: SearchPresenterFunc
getSearchTitle?: SearchPresenterFunc
}