@@ -539,11 +539,20 @@ function freeTextClause(query: string): string | undefined {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ответ Search → пары (Id элемента, его тип по префиксу Path).
|
// Ответ Search → пары (Id элемента, его тип по префиксу Path).
|
||||||
|
//
|
||||||
|
// Дедуп по (тип, Id) — ЗДЕСЬ, а не у вызывающей стороны: во всех запросах
|
||||||
|
// стоит TrimDuplicates: false (нужно, чтобы найти черновики и «свои» копии —
|
||||||
|
// стандартная дедупликация Search иногда схлопывает и их), а без неё индекс
|
||||||
|
// может вернуть один и тот же элемент несколькими хитами (переиндексация,
|
||||||
|
// несколько «версий» в crawl). Раньше хиты превращались в строки один-в-один,
|
||||||
|
// и дубликат из индекса становился дубликатом строки в таблице — с одинаковым
|
||||||
|
// React-ключом, то есть видимым «залипанием» одной и той же заявки дважды.
|
||||||
function hitsToEntries(
|
function hitsToEntries(
|
||||||
results: { PrimarySearchResults: unknown[] },
|
results: { PrimarySearchResults: unknown[] },
|
||||||
types: IRequestType[]
|
types: IRequestType[]
|
||||||
): Array<{ id: number; type: IRequestType }> {
|
): Array<{ id: number; type: IRequestType }> {
|
||||||
const urls = types.map((t) => ({ type: t, url: listAbsUrl(t).toLowerCase() }));
|
const urls = types.map((t) => ({ type: t, url: listAbsUrl(t).toLowerCase() }));
|
||||||
|
const seen = new Set<string>();
|
||||||
return (results.PrimarySearchResults as Array<Record<string, unknown>>)
|
return (results.PrimarySearchResults as Array<Record<string, unknown>>)
|
||||||
.map((r) => ({ id: Number(r.ListItemID), path: String(r.Path || '').toLowerCase() }))
|
.map((r) => ({ id: Number(r.ListItemID), path: String(r.Path || '').toLowerCase() }))
|
||||||
.filter((h) => !isNaN(h.id) && h.id > 0)
|
.filter((h) => !isNaN(h.id) && h.id > 0)
|
||||||
@@ -551,7 +560,13 @@ function hitsToEntries(
|
|||||||
const matched = urls.filter((u) => h.path.indexOf(u.url) === 0)[0];
|
const matched = urls.filter((u) => h.path.indexOf(u.url) === 0)[0];
|
||||||
return matched ? { id: h.id, type: matched.type } : undefined;
|
return matched ? { id: h.id, type: matched.type } : undefined;
|
||||||
})
|
})
|
||||||
.filter((e): e is { id: number; type: IRequestType } => !!e);
|
.filter((e): e is { id: number; type: IRequestType } => !!e)
|
||||||
|
.filter((e) => {
|
||||||
|
const key = `${e.type.id}-${e.id}`;
|
||||||
|
if (seen.has(key)) return false;
|
||||||
|
seen.add(key);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Дочитать поля заявок по найденным Id (Search отдаёт не все колонки, и для
|
// Дочитать поля заявок по найденным Id (Search отдаёт не все колонки, и для
|
||||||
|
|||||||
Reference in New Issue
Block a user