Есть ли параметр (или фрагмент), который я могу использовать для поиска частичных совпадений строк с использованием поиска по апострофу? Например: поиск по слову «синий» должен вернуть элемент с заголовком «Схема управления обучением».
Поиск неполных строк
Ответы (2)
Как вы знаете, я ведущий разработчик Apostrophe в P'unk Avenue.
Ваше решение действительно работает, однако одна серьезная проблема заключается в том, что вы не избегаете ввода пользователя, чтобы предотвратить интерпретацию метасимволов регулярного выражения, таких как .
и *
, как таковых. Для этого вы можете использовать apos.utils.regExpQuote(s)
, который возвращает строку с опасными символами, экранированными с помощью \
.
Однако есть лучший способ сделать это: просто используйте вместо этого req.query.autocomplete
. Апостроф имеет встроенный фильтр курсора autocomplete
, который работает иначе, чем фильтр search
. Фильтр autocomplete
допускает частичное совпадение (правда, только в начале слова), а затем пропускает найденные слова через обычный фильтр search
, так что результаты по-прежнему сортируются по качеству совпадения. Он также сохраняет большую часть преимущества в производительности от использования search
.
Поиск по регулярному выражению, подобный вашему, будет сканировать всю коллекцию mongodb (ну, по крайней мере, все документы соответствующего типа), а это означает, что у вас будут проблемы с производительностью, если у вас много контента.
Одно предостережение с autocomplete
заключается в том, что он «видит» только слова в высокоприоритетных полях, таких как заголовок, теги и т. д. Он не видит полный текст документа, как это может сделать ваш поиск по регулярному выражению (или фильтр search
). Это был необходимый компромисс, чтобы сохранить производительность.
Похоже, добавление RegExp - это то, что необходимо. Если кому-то еще это нужно, вот соответствующий код lib\modules\apostrophe-search\index.js:
module.exports = {
perPage: 15,
construct: function(self, options) {
self.indexPage = function(req, callback) {
req.query.search = req.query.search || req.query.q;
var allowedTypes;
var defaultingToAll = false;
var cursor = self.apos.docs.find(req, { lowSearchText: new RegExp(req.query.search, 'i') } )
.perPage(self.perPage);
if (self.filters) {
var filterTypes = _.filter(
_.pluck(self.filters, 'name'),
function(name) {
return name !== '__else';
}
);