@paroicms/server
Version:
The ParoiCMS server
85 lines • 3.61 kB
JavaScript
import { type } from "arktype";
import { dbAnyLanguage } from "../../context.js";
import { formatDocValues, querySelectDocValues, } from "../../rendering-payload/doc-values.queries.js";
const SearchTextCountAT = type({
cnt: "number",
"+": "reject",
});
export async function searchText(siteContext, options) {
const { words, language, start, limit, onlyPublished, orderBy = [{ fieldName: "publishDate", direction: "desc" }], } = options;
const query = createBaseSearchTextQueryBuilder(siteContext, { language, words, onlyPublished })
.distinct()
.limit(limit)
.offset(start);
querySelectDocValues(query);
if (orderBy && orderBy.length > 0) {
for (const i of orderBy) {
if (i.fieldName === "title") {
query.orderBy("d.title", i.direction);
}
else if (i.fieldName === "publishDate") {
query.orderBy("l.publishDate", i.direction);
}
}
}
const rows = await query;
let total;
if (rows.length < limit) {
total = start + rows.length;
}
else {
const countQuery = createBaseSearchTextQueryBuilder(siteContext, {
language,
words,
onlyPublished,
}).countDistinct("l.id as cnt");
const countResult = await countQuery.first();
total = countResult ? SearchTextCountAT.assert(countResult).cnt : 0;
}
return {
rows: rows.map((row) => formatDocValues(row, { language })),
total,
};
}
function createBaseSearchTextQueryBuilder(siteContext, { language, words, onlyPublished, }) {
const { cn } = siteContext;
const query = cn("PaDocument as d")
.innerJoin("PaLNode as s", {
"s.nodeId": "d.nodeId",
"s.language": "d.language",
})
.innerJoin("PaNode as l", "s.nodeId", "l.id")
.leftJoin("PaFieldVarchar as fv", function () {
this.on("fv.nodeId", "=", "s.nodeId").andOn(function () {
this.on("fv.language", "=", "s.language").orOn("fv.language", "=", cn.raw("?", [dbAnyLanguage]));
});
})
.leftJoin("PaFieldText as ft", function () {
this.on("ft.nodeId", "=", "d.nodeId").andOn(function () {
this.on("ft.language", "=", "d.language").orOn("ft.language", "=", cn.raw("?", [dbAnyLanguage]));
});
})
.where("s.language", language);
if (onlyPublished) {
query.where("s.ready", 1).whereRaw("l.publishDate <= current_timestamp");
}
for (let index = 0; index < words.length; index++) {
const wordPattern = `%${words[index]}%`;
query.andWhere(function () {
this.where("d.title", "like", wordPattern)
.orWhere("ft.val", "like", wordPattern)
.orWhere("fv.val", "like", wordPattern)
.orWhereRaw(`exists (
select 1
from PaNode l2
inner join PaPartNode p2 on p2.nodeId = l2.id
inner join PaLNode s2 on s2.nodeId = l2.id and s2.language = ?
left join PaFieldVarchar fv2 on fv2.nodeId = s2.nodeId and (fv2.language = s2.language or fv2.language = ?)
left join PaFieldText ft2 on ft2.nodeId = s2.nodeId and (ft2.language = s2.language or ft2.language = ?)
where p2.documentNodeId = l.id ${onlyPublished ? "and s2.ready = 1 and l2.publishDate <= current_timestamp" : ""} and (fv2.val like ? or ft2.val like ?)
)`, [language, dbAnyLanguage, dbAnyLanguage, wordPattern, wordPattern]);
});
}
return query;
}
//# sourceMappingURL=search-text.queries.js.map