Проблемы с дефисом в запросе Jackrabbit XPath - PullRequest
0 голосов
/ 26 августа 2010

Во-первых, позвольте мне сказать, что я очень плохо знаком с JSR-170 и Jackrabbit / Lucene в целом.

У меня следующий запрос XPath:

//*[@sling:resourceType="users/user-profile" and jcr:contains(*/*/*,'sophie\-a')] order by @jcr:score descending

У меня есть пользователь по имени Софи-Аллен и пользователь по имени Софи-Энн. Поиск с использованием вышеуказанного запроса возвращает ноль результатов, тогда как поиск только по «sophie» возвращает обоих пользователей. Я понимаю, что дефис означает исключение в JSR-170, но я избежал его (как вы можете видеть выше).

Почему этот запрос не возвращает обоих пользователей?

Еще одна странная вещь, когда я использую звездочки (все дефисы экранируются при выполнении):

  • Поиск 'sophie-allen' возвращает запись Софи-Аллен.
  • Поиск 'soph*' возвращает и Софи-Аллен, и Софи-Энн.
  • Поиск 'sophie-a* ничего не возвращает.
  • Поиск 'sophie-allen*' ничего не возвращает.

Я понимаю, что с jcr: содержит, технически вам не нужно использовать звездочки, но, глядя на вышеупомянутое поведение, кажется, что он имеет какой-то эффект.

Есть ли что-то еще, что мне не хватает в отношении дефисов и звездочек в запросах XPath и поиске JCR? Я погуглил все, что мог придумать, и прочитал спецификацию, но не могу найти ничего, что отвечало бы на мой вопрос.

Заранее спасибо.

Edit: Похоже, что «запрос фразы» не работает с jcr: Содержит (больше?), Поскольку Lucene Analyzer по умолчанию токенизирует дефис, что означает, что он разбивает 'sophie-allen' на sophie и allen.

Редактировать 2: Я попытался использовать собственный анализатор и токенизатор, как это было предложено кем-то из списка пользователей Jackrabbit, но это тоже не помогло, Lucene все еще использует дефис и пропускает результаты, которые я хочу.

Ответы [ 2 ]

2 голосов
/ 26 августа 2010

Вы правы, что Lucene делит "sophie-allen" на два токена, но эти токены находятся рядом.Вы сказали, что пробовали выражение фразы следующим образом:

... jcr:contains(*/*/*,'"sophie-a*"') ...

Это должно сработать, найдя токен «sophie», за которым следует другой токен, содержащий «a» в качестве первого символа.Поскольку тот же анализатор, который использовался во время индексации, должен использоваться для токенизации этого выражения фразы, символ «-» все равно будет использоваться в качестве разделителя [1].(Обратите внимание, что если вы задаете выражение XPath в коде Java, вам придется экранировать символы двойной кавычки с предыдущей обратной косой чертой.)

Однако, если это не сработает, вы можете попробовать выполнитьиз дефиса в этом выражении.Поскольку вы используете символы подстановки, логика может быть неправильно маркировать выражение подстановки.Другими словами, попробуйте:

... jcr:contains(*/*/*,'"sophie a*"') ...

Конечно, без подстановочных знаков, это, вероятно, будет работать (с дефисом или без него):

... jcr:contains(*/*/*,'"sophie-allen"') ...

Удачи!

PS Я не проверял, что это работает в Jackrabbit, но он работает в ModeShape (который также использует Lucene).

[1] Точные правила зависят от токенизатора.Например, StandardTokenizer отфильтровывает английские стоп-слова, но маркирует символ «-», кроме случаев, когда в токене есть число (в этом случае весь токен интерпретируется как продукт и не разделяется.

1 голос
/ 25 ноября 2010

Работая над этим с коллегой, мы обнаружили это JIRA для ModeShape, случайно зарегистрированное Рэндаллом (который также ответил здесь).Оказывается, проблема вызвана тем, что крольчонок не обрабатывает подстановочный знак в поисковом запросе с подстановочным знаком правильно / слишком хорошо.

Рэндалл сделал исправление для ModeShape, но мои коллеги и команда проектаноминирован не для того, чтобы решить нашу проблему на данном этапе, так как использование Jackrabbit не было на 100% уверенным.

Я бы хотел связать ответ на этот вопрос с Рэндаллом, но его пост не является настоящим ответом.Я отмечу этот пост как ответ, если Рэндалл не придет и не напишет что-нибудь.

...