UBER-828: Fix slow value filter (#3676)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2023-09-11 12:40:31 +07:00 committed by GitHub
parent c5a97b163c
commit f281fa1149
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -16,20 +16,20 @@
import core, { Class, Doc, FindResult, getObjectValue, Ref, SortingOrder, Space } from '@hcengineering/core' import core, { Class, Doc, FindResult, getObjectValue, Ref, SortingOrder, Space } from '@hcengineering/core'
import presentation, { getClient } from '@hcengineering/presentation' import presentation, { getClient } from '@hcengineering/presentation'
import ui, { import ui, {
deviceOptionsStore,
EditWithIcon, EditWithIcon,
Icon, Icon,
IconSearch,
IconCheck, IconCheck,
IconSearch,
Label, Label,
Loading, Loading,
resizeObserver, resizeObserver
deviceOptionsStore
} from '@hcengineering/ui' } from '@hcengineering/ui'
import { Filter } from '@hcengineering/view' import { Filter } from '@hcengineering/view'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { getPresenter } from '../../utils'
import { FILTER_DEBOUNCE_MS, sortFilterValues } from '../../filter' import { FILTER_DEBOUNCE_MS, sortFilterValues } from '../../filter'
import view from '../../plugin' import view from '../../plugin'
import { getPresenter } from '../../utils'
export let _class: Ref<Class<Doc>> export let _class: Ref<Class<Doc>>
export let space: Ref<Space> | undefined = undefined export let space: Ref<Space> | undefined = undefined
@ -79,36 +79,49 @@
? [] ? []
: (await client.findAll(core.class.Space, { archived: true }, { projection: { _id: 1 } })).map((it) => it._id) : (await client.findAll(core.class.Space, { archived: true }, { projection: { _id: 1 } })).map((it) => it._id)
objectsPromise = client.findAll( async function doQuery (limit: number | undefined, first1000?: any[]): Promise<void> {
_class, const p = client.findAll(
{ _class,
...resultQuery, {
...(space ? { space } : isDerivedFromSpace ? { archived: false } : { space: { $nin: archived } }) ...resultQuery,
}, ...(space ? { space } : isDerivedFromSpace ? { archived: false } : { space: { $nin: archived } }),
{ ...(first1000 ? { [filter.key.key]: { $nin: first1000 } } : {})
sort: { [filter.key.key]: SortingOrder.Ascending }, },
projection: { [prefix + filter.key.key]: 1, space: 1 }, {
...(space || isDerivedFromSpace ? {} : { lookup: { space: core.class.Space } }) sort: { modifiedOn: SortingOrder.Descending },
projection: { [prefix + filter.key.key]: 1 },
...(limit !== undefined ? { limit } : {})
}
)
if (limit !== undefined) {
objectsPromise = p
} }
) const res = await p
const res = await objectsPromise
for (const object of res) { for (const object of res) {
let asDoc = object let asDoc = object
if (hierarchy.isMixin(filter.key._class)) { if (hierarchy.isMixin(filter.key._class)) {
asDoc = hierarchy.as(object, filter.key._class) asDoc = hierarchy.as(object, filter.key._class)
}
const realValue = getObjectValue(filter.key.key, asDoc)
const value = getValue(realValue)
values.add(value)
realValues.set(value, (realValues.get(value) ?? new Set()).add(realValue))
}
for (const object of filter.value.map((p) => p[0])) {
values.add(object)
} }
const realValue = getObjectValue(filter.key.key, asDoc)
const value = getValue(realValue)
values.add(value)
realValues.set(value, (realValues.get(value) ?? new Set()).add(realValue))
}
for (const object of filter.value.map((p) => p[0])) {
values.add(object)
} }
await doQuery(1000)
values = values values = values
sortedValues = sortFilterValues([...values.keys()], (v) => isSelected(v, selectedValues)) sortedValues = sortFilterValues([...values.keys()], (v) => isSelected(v, selectedValues))
objectsPromise = undefined objectsPromise = undefined
// Check if we have all possible values, in case of enumeration
await doQuery(undefined, Array.from(values))
sortedValues = sortFilterValues([...values.keys()], (v) => isSelected(v, selectedValues))
objectsPromise = undefined
} }
function getValue (obj: any): any { function getValue (obj: any): any {