Search fix (#1352)

Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
This commit is contained in:
Denis Bykhov 2022-04-11 14:22:04 +06:00 committed by GitHub
parent 662cca9282
commit 124e37d29e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 28 deletions

View File

@ -145,28 +145,33 @@ export class FullTextIndex implements WithFind {
if ($search === undefined) return toFindResult([])
let skip = 0
const result: FindResult<T> = toFindResult([])
const ids: Set<Ref<Doc>> = new Set<Ref<Doc>>()
const baseClass = this.hierarchy.getBaseClass(_class)
const classes = this.hierarchy.getDescendants(baseClass)
const fullTextLimit = 10000
while (true) {
const docs = await this.adapter.search(_class, query, options?.limit, skip)
if (docs.length === 0) {
result.total = result.length
return result
}
skip += docs.length
const ids: Set<Ref<Doc>> = new Set<Ref<Doc>>(docs.map((p) => p.id))
const docs = await this.adapter.search(classes, query, fullTextLimit, skip)
for (const doc of docs) {
ids.add(doc.id)
if (doc.attachedTo !== undefined) {
ids.add(doc.attachedTo)
}
}
const resultIds = getResultIds(ids, _id)
const current = await this.dbStorage.findAll(ctx, _class, { _id: { $in: resultIds }, ...mainQuery }, options)
result.push(...current)
result.total += current.total
if (result.length > 0 && result.length >= (options?.limit ?? 0)) {
return result
if (docs.length < fullTextLimit) {
break
}
skip += docs.length
}
const resultIds = getResultIds(ids, _id)
const { limit, ...otherOptions } = options ?? { }
const result = await this.dbStorage.findAll(ctx, _class, { _id: { $in: resultIds }, ...mainQuery }, otherOptions)
const total = result.total
result.sort((a, b) => resultIds.indexOf(a._id) - resultIds.indexOf(b._id))
if (limit !== undefined) {
const res = toFindResult(result.splice(0, limit), total)
return res
}
return toFindResult(result, total)
}
private getFullTextAttributes (clazz: Ref<Class<Obj>>, parentDoc?: Doc): AnyAttribute[] {

View File

@ -68,7 +68,7 @@ export interface FullTextAdapter {
index: (doc: IndexedDoc) => Promise<TxResult>
update: (id: Ref<Doc>, update: Record<string, any>) => Promise<TxResult>
remove: (id: Ref<Doc>) => Promise<void>
search: (_class: Ref<Class<Doc>>, search: DocumentQuery<Doc>, size: number | undefined, from?: number) => Promise<IndexedDoc[]>
search: (_classes: Ref<Class<Doc>>[], search: DocumentQuery<Doc>, size: number | undefined, from?: number) => Promise<IndexedDoc[]>
close: () => Promise<void>
}

View File

@ -30,7 +30,7 @@ describe('client', () => {
content0: 'hey there!'
}
await adapter.index(doc)
const hits = await adapter.search('class1' as Ref<Class<Doc>>, {}, 1)
const hits = await adapter.search(['class1' as Ref<Class<Doc>>], {}, 1)
console.log(hits)
})

View File

@ -25,7 +25,7 @@ class ElasticAdapter implements FullTextAdapter {
await this.client.close()
}
async search (_class: Ref<Class<Doc>>, query: DocumentQuery<Doc>, size: number | undefined, from: number | undefined): Promise<IndexedDoc[]> {
async search (_classes: Ref<Class<Doc>>[], query: DocumentQuery<Doc>, size: number | undefined, from: number | undefined): Promise<IndexedDoc[]> {
if (query.$search === undefined) return []
const request: any = {
bool: {
@ -39,11 +39,9 @@ class ElasticAdapter implements FullTextAdapter {
],
should: [
{
term: {
_class: {
value: _class,
case_insensitive: true
}
terms: {
_class: _classes.map((c) => c.toLowerCase()),
boost: 10.0
}
}
]
@ -53,12 +51,9 @@ class ElasticAdapter implements FullTextAdapter {
if (query.space != null) {
if (typeof query.space === 'object' && query.space.$in !== undefined) {
request.bool.should.push({
term: {
space: {
value: query.space.$in,
boost: 2.0,
case_insensitive: true
}
terms: {
space: query.space.$in.map((c) => c.toLowerCase()),
boost: 2.0
}
})
} else {