Поиск неполных строк

Есть ли параметр (или фрагмент), который я могу использовать для поиска частичных совпадений строк с использованием поиска по апострофу? Например: поиск по слову «синий» должен вернуть элемент с заголовком «Схема управления обучением».


person lance-p    schedule 08.11.2016    source источник
comment
В моем тесте поиск частичной строки синего цвета работает: var cursor = self.apos.docs.find(req, { lowSearchText: /blue/ } ), но создание переменной не работает. Разве это не должно быть эквивалентно и работать? вар searchText = 'синий'; var cursor = self.apos.docs.find(req, {lowSearchText: searchText})   -  person lance-p    schedule 09.11.2016


Ответы (2)


Как вы знаете, я ведущий разработчик Apostrophe в P'unk Avenue.

Ваше решение действительно работает, однако одна серьезная проблема заключается в том, что вы не избегаете ввода пользователя, чтобы предотвратить интерпретацию метасимволов регулярного выражения, таких как . и *, как таковых. Для этого вы можете использовать apos.utils.regExpQuote(s), который возвращает строку с опасными символами, экранированными с помощью \.

Однако есть лучший способ сделать это: просто используйте вместо этого req.query.autocomplete. Апостроф имеет встроенный фильтр курсора autocomplete, который работает иначе, чем фильтр search. Фильтр autocomplete допускает частичное совпадение (правда, только в начале слова), а затем пропускает найденные слова через обычный фильтр search, так что результаты по-прежнему сортируются по качеству совпадения. Он также сохраняет большую часть преимущества в производительности от использования search.

Поиск по регулярному выражению, подобный вашему, будет сканировать всю коллекцию mongodb (ну, по крайней мере, все документы соответствующего типа), а это означает, что у вас будут проблемы с производительностью, если у вас много контента.

Одно предостережение с autocomplete заключается в том, что он «видит» только слова в высокоприоритетных полях, таких как заголовок, теги и т. д. Он не видит полный текст документа, как это может сделать ваш поиск по регулярному выражению (или фильтр search). Это был необходимый компромисс, чтобы сохранить производительность.

person Tom Boutell    schedule 17.11.2016

Похоже, добавление 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';
                }
            );
person lance-p    schedule 09.11.2016