а то что у меня в полях name, description тип поля указан как jsonB
insert into "vacancy_fts" ("vacancy_id", "vector") select v.id,
setweight(to_tsvector('russian_ispell',v.name), 'A') ||
SELECT s.user_id FROM subscription_fts as u
LEFT JOIN vacancy_fts as v ON s.vector = v.vector
WHERE v.id = :id
-- при создании вакансии нужно заполнить индекс
insert into "vacancy_fts" ("vacancy_id", "vector") select v.id,
setweight(to_tsvector('russian_ispell',v.name), 'A') ||
setweight(to_tsvector('russian_ispell',coalesce(v.description,'')), 'B') ||
setweight(to_tsvector('russian_ispell',coalesce(k.tags,'')), 'D') -- pseudo
from "vacancies" as "v" left join "keywords" as k -- on ...
where v.id=:id
DB::table('vacancy_fts')
->whereFullText('vector', 'web developer')
->get();
key_words: ключевые слова из формы
при создании вакансии: description
function initModal() {
const modalApp = document.getElementById("modal-application");
// чтобы не было коллизий из-за -того, что модалка и бэкдроп вложены в кнопку открывающую из
// вообще стандарт модалок - в body. иначе это попап
document.body.appendChild(modalApp);
// из-за того что окно модалки вложено в бэкдроп нужно запретить проброс события
// на родителя (бэкдроп) при клике на модалку
modalApp.firstElementChild.addEventListener("click", e =>e.stopPropagation());
const closeBtn = modalApp.getElementsByClassName("modal-close-btn")[0];
const close = () => modalApp.classList.remove("open");
const open = () => modalApp.classList.add("open");
modalApp.addEventListener("click", close);
closeBtn.addEventListener("click", close);
window.addEventListener("keydown", e => { if (e.key === "Escape") close(); });
return { open, close };
}
var myModal = initModal();
document.getElementById("open-modal-btn").addEventListener("click", myModal.open);
индекс на обновлении вакансий. имхо лучше в отдельной таблице.
"безболезненный" truncate на весь индекс и полная перестройка.