оценка elastica на основе регулярного выражения с использованием mvel

Я новичок в эластичном поиске, и вот мой сценарий, который я пытаюсь решить. У меня есть поле ввода поиска, которое поддерживает логику самовнушения. Результаты извлекаются из эластичного индекса, который использует фильтр ngram. Что я хочу улучшить, так это ввести возможность подсчета очков, чтобы упорядочивать результаты от наиболее важных к менее важным (в зависимости от оценки). Оценка должна основываться на следующих случаях:

  • Если есть совпадение, которое начинается с данной строки, установите счет 100
  • Если есть совпадение, содержащее заданную строку и не начинающееся с нее, установите счет равным 10.

Для этой цели был реализован скрипт elastica с операторами mvel для поддержки соответствия регулярным выражениям. Другими словами, он проверяет, соответствует ли значение слева регулярному выражению справа (только тогда переменная соответственно увеличивается). Но, к сожалению, это происходит неправильно, когда строка поиска зависит от языка, несмотря на то, что значение слева также относится к указанному языку. Еще одна проблема, с которой нужно справиться, - это второй случай, о котором я упоминал выше (не могу заставить его работать).

Скрипт, когда значение («один пример» (принадлежит к полю имени)) начинается с заданного слова («один»), работает нормально.

$testParam = mb_strtolower('one', 'utf-8');
$regexStart = '^' . $testParam . '.*$';
$ElasticaScript = new Elastica_Script(" total = 1; if(doc['name'].value ~= '{$regexStart}'){ total += 100; } return total; ");

Скрипт, когда значение («один пример» (принадлежит к полю имени)) содержит заданное слово («пример»), не работает, и в результате общий балл остается равным 1, а не увеличивается до 11, как должно быть.

$testParam = mb_strtolower('example', 'utf-8');
$regexStart = '^.*' . $testParam . '.*$';
$ElasticaScript = new Elastica_Script(" total = 1; if(doc['name'].value ~= '{$regexStart}'){ total += 10; } return total; ");

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

Вся работа была сделана с помощью резинки, не говоря уже о php. Не могли бы вы помочь решить мою проблему? Если есть другой подход/решение, не стесняйтесь поделиться им со мной.

заранее спасибо


person elviento    schedule 09.11.2013    source источник
comment
Опубликуйте свой сценарий, что произойдет, когда вы попробуете его, и что вы ожидаете.   -  person kielni    schedule 09.11.2013
comment
Привет, kielni, я разместил это.   -  person elviento    schedule 10.11.2013


Ответы (1)


doc['name'].value загружает проанализированную версию поля. Если для вашего поля не установлено значение «Не анализируется», оно, скорее всего, будет сильно отличаться от исходного содержимого поля и не будет полезно для сопоставления регулярных выражений. Документация Elasticsearch по полям сценария скажем, это имеет смысл только для неанализируемых полей или полей с одним термином. Например, если ваш контент проиндексирован как ngrams, это значение будет состоять из ngrams.

Вы можете получить доступ к исходному тексту поля, используя _source.field_name, а затем вычислить свою оценку на его основе. Вы по-прежнему можете выполнять поиск, как обычно, по ngrams и использовать _source только для подсчета очков.

Вот пример запроса function_score, в котором оценка по умолчанию равна _score, добавляется 100, если поле имени начинается с единицы, и добавляется 10, если поле имени содержит единицу в любом другом месте. Он использует _source.name для доступа к содержимому поля имени, поэтому он выполняет регулярное выражение с исходным текстом поля имени, а не с ngrams, рассчитанными из поля имени.

{
  "query": {
    "function_score": {
      "boost_mode": "replace",
      "script_score": {
        "script": "total = _score; if (_source.name ~= '^one.*') { total += 100 } else if (_source.name ~= '.*?one.*?') { total += 10 } return total"
      }
    }
  }
}
person kielni    schedule 11.11.2013