mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-11 12:57:59 +00:00
UBERF-5018: search improvements/Indexing fix (#4403)
Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
parent
27c428602a
commit
28dca6632c
@ -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, {
|
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||||
|
@ -45,8 +45,8 @@ export class TObjectDDParticipant extends TClass implements ObjectDDParticipant
|
|||||||
@Mixin(serverCore.mixin.SearchPresenter, core.class.Class)
|
@Mixin(serverCore.mixin.SearchPresenter, core.class.Class)
|
||||||
export class TSearchPresenter extends TClass implements SearchPresenter {
|
export class TSearchPresenter extends TClass implements SearchPresenter {
|
||||||
searchConfig!: ClassSearchConfig
|
searchConfig!: ClassSearchConfig
|
||||||
getSearchShortTitle!: Resource<SearchPresenterFunc>
|
getSearchShortTitle!: SearchPresenterFunc
|
||||||
getSearchTitle!: Resource<SearchPresenterFunc>
|
getSearchTitle!: SearchPresenterFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createModel (builder: Builder): void {
|
export function createModel (builder: Builder): void {
|
||||||
|
@ -65,10 +65,13 @@ export function createModel (builder: Builder): void {
|
|||||||
props: ['number']
|
props: ['number']
|
||||||
},
|
},
|
||||||
title: {
|
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(
|
builder.mixin(
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import type { Plugin, Resource } from '@hcengineering/platform'
|
import type { Plugin, Resource } from '@hcengineering/platform'
|
||||||
import { plugin } 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'
|
import { Presenter } from '@hcengineering/server-notification'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,6 +38,6 @@ export default plugin(serverContactId, {
|
|||||||
OrganizationHTMLPresenter: '' as Resource<Presenter>,
|
OrganizationHTMLPresenter: '' as Resource<Presenter>,
|
||||||
OrganizationTextPresenter: '' as Resource<Presenter>,
|
OrganizationTextPresenter: '' as Resource<Presenter>,
|
||||||
|
|
||||||
ContactNameProvider: '' as Resource<SearchPresenterFunc>
|
ContactNameProvider: '' as Resource<SearchPresenterProvider>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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) {
|
if (doc.attachedToClass != null && doc.attachedTo != null) {
|
||||||
const propagate: Ref<Class<Doc>>[] = collectPropagate(pipeline, doc.attachedToClass)
|
const propagate: Ref<Class<Doc>>[] = collectPropagate(pipeline, doc.attachedToClass)
|
||||||
if (propagate.some((it) => pipeline.hierarchy.isDerived(doc.objectClass, it))) {
|
if (propagate.some((it) => pipeline.hierarchy.isDerived(doc.objectClass, it))) {
|
||||||
// We need to include all parent content into this one.
|
// We need to include all parent content into this one.
|
||||||
const [parentDoc] = await metrics.with(
|
;[parentDoc] = await metrics.with(
|
||||||
'find-parent',
|
'find-parent',
|
||||||
{},
|
{},
|
||||||
async (ctx) =>
|
async (ctx) =>
|
||||||
|
@ -107,4 +107,4 @@ export const fieldStateId = 'fld-v11'
|
|||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export const fullTextPushStageId = 'fts-v9'
|
export const fullTextPushStageId = 'fts-v9bc'
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Class, Doc, DocIndexState, docKey, Hierarchy, Ref, RefTo, SearchResultDoc } from '@hcengineering/core'
|
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 plugin from './plugin'
|
||||||
import { ClassSearchConfigProps, IndexedDoc, SearchPresenter, SearchScoring } from './types'
|
import { ClassSearchConfigProps, IndexedDoc, SearchPresenter, SearchPresenterFunc, SearchScoring } from './types'
|
||||||
|
|
||||||
interface IndexedReader {
|
interface IndexedReader {
|
||||||
get: (attribute: string) => any
|
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> = {}
|
const res: Record<string, any> = {}
|
||||||
for (const prop of props) {
|
for (const prop of props) {
|
||||||
if (typeof prop === 'string') {
|
if (typeof prop === 'string') {
|
||||||
@ -48,7 +55,18 @@ function readAndMapProps (reader: IndexedReader, props: ClassSearchConfigProps[]
|
|||||||
for (const [propName, rest] of Object.entries(prop)) {
|
for (const [propName, rest] of Object.entries(prop)) {
|
||||||
if (rest.length > 1) {
|
if (rest.length > 1) {
|
||||||
const val = reader.getDoc(rest[0])?.get(rest[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
|
let value
|
||||||
if (prop.config.tmpl !== undefined) {
|
if (prop.config.tmpl !== undefined) {
|
||||||
const tmpl = prop.config.tmpl
|
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)
|
value = fillTemplate(tmpl, renderProps)
|
||||||
} else if (typeof prop.config === 'string') {
|
} else if (typeof prop.config === 'string') {
|
||||||
value = reader.get(prop.config)
|
value = reader.get(prop.config)
|
||||||
} else if (prop.provider !== undefined) {
|
} else if (prop.provider !== undefined) {
|
||||||
const func = (await getResource(prop.provider)) as any
|
const func = await getResource(Object.values(prop.provider)[0] as Resource<any>)
|
||||||
const renderProps = readAndMapProps(reader, prop.config.props)
|
const renderProps = await readAndMapProps(reader, prop.config.props)
|
||||||
value = func(hierarchy, { _class: elasticDoc._class, ...renderProps })
|
value = func(hierarchy, { _class: elasticDoc._class, ...renderProps })
|
||||||
} else if (prop.name === 'searchIcon') {
|
} else if (prop.name === 'searchIcon') {
|
||||||
value = readAndMapProps(reader, prop.config.props)
|
value = await readAndMapProps(reader, prop.config.props)
|
||||||
}
|
}
|
||||||
elasticDoc[prop.name] = value
|
elasticDoc[prop.name] = value
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,11 @@ export type SearchProps = Record<string, string>
|
|||||||
/**
|
/**
|
||||||
* @public
|
* @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
|
* @public
|
||||||
@ -386,6 +390,6 @@ export interface ClassSearchConfig {
|
|||||||
*/
|
*/
|
||||||
export interface SearchPresenter extends Class<Doc> {
|
export interface SearchPresenter extends Class<Doc> {
|
||||||
searchConfig: ClassSearchConfig
|
searchConfig: ClassSearchConfig
|
||||||
getSearchShortTitle?: Resource<SearchPresenterFunc>
|
getSearchShortTitle?: SearchPresenterFunc
|
||||||
getSearchTitle?: Resource<SearchPresenterFunc>
|
getSearchTitle?: SearchPresenterFunc
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user