Я занимаюсь обновлением и тестированием большой установки и обнаружил одну проблему, которую не могу понять.У меня есть большая коллекция документов, в которой мой индекс создается следующим образом:
<collection xmlns="http://exist-db.org/collection-config/1.0">
<index xmlns:mods="http://www.loc.gov/mods/v3" xmlns:xlink="http://www.w3.org/1999/xlink">
<fulltext default="none" attributes="false"/>
<lucene>
<analyzer class="org.apache.lucene.analysis.standard.StandardAnalyzer">
<param name="stopwords" type="org.apache.lucene.analysis.util.CharArraySet"/>
</analyzer>
<analyzer id="ws" class="org.apache.lucene.analysis.WhitespaceAnalyzer"/>
<text qname="p"/>
<text qname="li"/>
<text qname="h1"/>
<text qname="h2"/>
<text qname="h3"/>
</lucene>
</index>
</collection>
В моей версии 2 это прекрасно работает.Запрос возвращает только элемент в списке (p, li, h1, h2, h3).Также only возвращает те элементы с текстом в элементе (как и ожидалось).Функция поиска:
declare function ls:ls($collection as xs:string, $phrase as xs:string) as element()* {
for $hit in collection(xmldb:encode-uri($collection))//*[ft:query(.,
<query>
<phrase>{$phrase}</phrase>
</query>
)]
order by $hit/ancestor::div[@class='content']/@doc/string()
return
<tr>
<td>
{$hit/ancestor::div[@class='content']/@doc/string()}
</td>
<td>
{$hit/ancestor::div[@class='content']/@title/string()}
</td>
<td>
{local-name($hit)}
</td>
<td class="hit_text">
{normalize-space($hit)}
</td>
</tr>
};
Чтобы увидеть результат, вот снимок результатов веб-страницы:
Конечно, это не все результаты, но, поверьте мне ... это только возврат именованных элементов и только тех, в которых есть «сердце».
После экспорта / импорта контента в новую версию4 установка почти все остальное работает отлично.Однако даже после переиндексации содержимого тот же самый xQuery возвращает нежелательные элементы более высокого уровня (например, div), а также элементы, которые не содержат поисковую фразу.
Например, этот же запрос показывает такой же результат:
Теперь, как ни странно, если я изменю функцию, чтобы удалить подстановочный знак и идти только после "h1" (или любого другого из названных элементов), это работает:
for $hit in collection(xmldb:encode-uri($collection))//h1[ft:query(.,
Выход:
Вы можете видеть, что в отличие от предыдущего примера, h1 без "сердца""не возвращается.
Что я пропустил в своем обновлении?есть ли какие-то изменения в Lucene, которые я пропустил или не понимаю?
Обновление
Как хак (ИМХО), это работает:
let $targets := collection(xmldb:encode-uri($collection))//*[local-name(.) = 'p' or local-name(.) = 'h1' or local-name(.) = 'h2' or local-name(.) = 'h3' or local-name(.) = 'li']
for $hit in $targets[ft:query(.,
<query>
<phrase>{$phrase}</phrase>
</query>
)]
Но если я удаляю созданиенабор узлов $ target и помещает collection () в «for», тогда он не работает.
Update II
Должно быть что-то не так (так как полный текст не включен иливыполняется или?) потому что выполнение одного и того же запроса в обоих случаях занимает way на новом обновленном сервере.
Так что же я упустил в обновлении?У меня есть conf.xml с призывом к Lucene в обоих случаях.Любые намеки на то, что искать, было бы замечательно.
Обновление III
Может быть, это в журналах проблема?Я сомневаюсь, что поиск в журнале версии 2.x показывает ту же ошибку.
2018-12-19 19:27:05,570 [qtp14962548-143] ERROR (AnalyzerConfig.java [configureAnalyzer]:173) - Lucene index: analyzer class org.apache.lucene.analysis.WhitespaceAnalyzer not found. (org.apache.lucene.analysis.WhitespaceAnalyzer)
2018-12-19 19:27:38,852 [qtp14962548-43] INFO (NativeBroker.java [reindexCollection]:1844) - Start indexing collection /db/EIDO/data/Core
2018-12-19 19:27:54,837 [qtp14962548-43] INFO (NativeBroker.java [reindexCollection]:1854) - Finished indexing collection /db/EIDO/data/Core in 15985 ms.
Обновление IV
Я изменил файл collection.xconf, как предложено, для удаления стоп-слов и удаленияWhitespaceAnalyzer:
<collection xmlns="http://exist-db.org/collection-config/1.0">
<index xmlns:mods="http://www.loc.gov/mods/v3" xmlns:xlink="http://www.w3.org/1999/xlink">
<fulltext default="none" attributes="false"/>
<lucene>
<analyzer class="org.apache.lucene.analysis.standard.StandardAnalyzer"/>
<text qname="p"/>
<text qname="li"/>
<text qname="h1"/>
<text qname="h2"/>
<text qname="h3"/>
</lucene>
</index>
</collection>
Я переиндексировал коллекцию.Из журнала:
2018-12-20 02:14:56,803 [qtp31631875-34] INFO (NativeBroker.java [reindexCollection]:1844) - Start indexing collection /db/EIDO/data/Core
2018-12-20 02:15:16,553 [qtp31631875-34] INFO (NativeBroker.java [reindexCollection]:1854) - Finished indexing collection /db/EIDO/data/Core in 19750 ms.
Я получаю точно такой же результат.
Обновление V
Я предполагаю, что я собираюсь.Собираюсь снова запустить весь процесс в эти выходные, удалить все и повторить попытку, но это не имеет смысла и не работает.
Обновление VI
Я не люблю толкаться!Теперь, глядя на результаты, по сути, этот поиск в текущей установке:
for $hit in collection(xmldb:encode-uri($collection))//*[ft:query(.,
<query>
<phrase>{$phrase}</phrase>
</query>
)]
Возвращает каждый элемент в базе данных, независимо от того, содержит он $ фразу или нет.Возвращает div, потом child p, потом, возможно, span span.Все они.Неважно, существует ли слово на самом деле в тексте.
Если я заменим подстановочный знак «*» на «h1», он возвращает только те h1, которые на самом деле содержат этот текст.Значит что-то не так или сломано или?Я, конечно, могу изменить список элементов, передаваемых в запрос ft: точным элементам (p, h1, h2, h3, li), но этот запрос будет длиться вечно через 4,5, а несколько секунд за 2.
Вероятно, последнее обновление
Я сдался и переустановил все, включая Monex.Я реэкспортировал существующую БД и импортировал ее.Я только изменяю порт на 80, хотя есть и другие изменения, которые я обычно делаю.
Теперь, даже пытаясь запустить панель мониторинга (после импорта), выдает:
javax.servlet.ServletException: javax.servlet.ServletException: An error occurred while processing request to /exist/apps/dashboard/: err:XPST0081 error found while loading module restxq: Error while loading module modules/restxq.xql: Invalid qname text:groups
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:724)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:531)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:760)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:678)
Что указывает мне на то, чтоэкспорт базы данных, а затем повторный импорт никогда не будут работать, если у вас установлены другие приложения.
К сожалению, мне приходится разбираться и искать альтернативные решения.Я мог попытаться просто восстановить данные или что-то в этом роде, но в приложении было 10 000 пользователей.Это не может быть воссоздано.
В настоящее время я могу только сказать, что оно не готово к прайм-тайму и просто будет сидеть на старой базе данных, которая отлично работает и работала годами.
И просто заметьте ... после установки свежей, чистой базы данных и без изменений я могу получить доступ к Monex или панели инструментов.Если я импортирую из своей резервной копии (как требуется, потому что она не совместима с двоичным кодом), все это ломается.
Это очевидная проблема для разработчиков.
Обновление снова
Я сделал полностью чистую установку.После этого я могу получить доступ к Monex без проблем.Затем я восстановил свою базу данных.ПРИМЕЧАНИЕ. В момент его завершения возникает вопрос о том, хочу ли я обновить приложения.Не уверен, что правильный ответ, может быть, это одна проблема, и я отвечаю неправильно (я отвечаю нет).
После того, как все будет переустановлено, я смогу нормально добраться до БД и всего моего приложения.Но при попытке запустить Monex теперь я получаю:
<exception>
<path>/db/apps/monex/modules/view.xql</path>
<message>err:XPST0081 error found while loading module indexes: Error while loading module indexes.xqm: Invalid qname text:index-terms</message>
</exception>
Правильный ли ответ да для обновления приложений?Я предполагаю, что это означает, что Monex, который я установил только с чистой установкой, перезаписывается моей резервной копией версии 2, и это вызывает ошибку.
Я взломал часть индекса monex, вызывающую проблему, и получил Monexбежать.Итак, он использует Lucene:
Итак, одно наблюдение заключается в том, почему Monex работает нормально, но восстановление моей (старой) БД убивает его.Это не должно быть AFAIK.
возможно, кто-то может объяснить этот результат мне, я не понимаю второй пункт, но я подозреваю, что это тот, который возвращает все:
ОК, работает
Итак.Во-первых, я понял, что восстановление моего / db разрушит все / apps (например, monex) в новой установке.Кажется странным для меня или плохое планирование моего или других.Таким образом, чтобы решить эту проблему, у меня есть новая резервная копия установки.
После установки новой версии eXist я восстанавливаю свою старую базу данных, а затем сразу же возобновляю новую установку заново.Это переписывает все / apps (например, monex) с последними версиями, которые были установлены из моей резервной копии, но не разрушает мою.Извините, смешно.
Теперь после этого я смог проверить и увидеть, используется ли индекс Lucene.Но это все, что он сказал мне, ничего больше (как я подозревал).
Очевидно, что в интеграции Lucene изменилось поведение.В моей старой версии я отправлял каждый элемент, и он возвращал только хиты.В этой новой версии вы не можете сделать это.Если вы отправите что-то похожее, что сделано в приведенном выше коде, оно все равно вернет его как «хит», даже если его нет.Таким образом, $ collection // * отправляет всю структуру в запрос и возвращает все, независимо от того, есть попадание или нет.Раньше он так себя не вел.
Таким образом, решение (которое я так ненавижу даже говорить) - вы можете отправлять только элементы запроса, который вы хотите найти, чтобы увидеть, есть лиэто контент, который является хитом.ВОТ ЭТО ДА.Опять извините, но если я ошибаюсь, пожалуйста, покажите мне, но это полный взлом.Если я создаю индекс всех p, я ожидаю, что p вернется, только если я выполню общий поиск, отправив его p, h1 и т. Д. Что происходит сейчас, это отправляет все обратно, ударил или нет, если вы не попросите точно то же самоеимя элемента, который вы проиндексировали.
Это похоже на поздний / ранний переплет.В старом eXist я отправлял $ coll / [ft: query ... и он возвращал то, что было у меня в качестве идентифицированных элементов в моем индексе.Теперь это не работает таким образом, поэтому вы не можете выполнить цикл for для $ coll / [ft: query ..., поскольку он по-прежнему возвращает everything .ИМХО, что это неправильно.
Итак, чтобы решить, я сделал это, в основном сначала выполнил поиск, а затем перебрал результаты.
declare function ls:ls($collection as xs:string, $phrase as xs:string) as element()* {
let $coll := collection(xmldb:encode-uri($collection))
let $hits := ($coll//p | $coll//li | $coll//h1 | $coll//h2 | $coll//h3)[ft:query(.,
<query>
<phrase>{$phrase}</phrase>
</query>
)]
for $hit in $hits
order by $hit/ancestor::div[@class='content']/@doc/string()
return
<tr>
<td>
{$hit/ancestor::div[@class='content']/@doc/string()}
</td>
<td>
{$hit/ancestor::div[@class='content']/@title/string()}
</td>
<td>
{local-name($hit)}
</td>
<td class="hit_text">
{normalize-space($hit)}
</td>
</tr>
}
;
А теперь яобновлен для тестирования, и это также работает:
let $hits := (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
<query>
<phrase>{$phrase}</phrase>
</query>
)]
for $hit in $hits ...
Так что теперь это так близко к тому, что у меня было раньше, мне НЕ нужно переходить к явным элементам, что правильно.Проблема в том, что теперь они не могут быть в цикле for.
Ключ здесь:
(collection(xmldb:encode-uri($collection))//*)
против:
collection(xmldb:encode-uri($collection))//*
И так ... всеэтого ... и решение заключается в том, что цикл for должен быть:
for $hit in (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
<query>
<phrase>{$phrase}</phrase>
</query>
)]
Так как это теперь решено, возможно, кто-то хотел бы объяснить, почему старый код, который сделалне использовать () для отдельных элементов, работающих, но не в последнем eXist.
Если быть точным, у меня открыты обе системы для тестирования.
Версия 2x:
for $hit in collection(xmldb:encode-uri($collection))//*[ft:query(.,
Одна секунда, правильный ответ.
for $hit in (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
17 секунд, правильный ответ.
Версия 4.5:
for $hit in collection(xmldb:encode-uri($collection))//*[ft:query(.,
10 секунд, совершенно неправильный ответ (возвращены div и non-hit)
for $hit in (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
одна секунда, правильный ответ.
Мне кажетсячто в старом eXist запрос ничего не возвращал, и в этом новом eXist, похоже, он возвращает результат для каждого отправленного элемента, а если индекс не существует, он все равно возвращает его.
Последнее обновлениеte
Просматривая чистую установку conf.xml
, я нашел комментарий в записи xquery для enable-query-rewriting
.Этот комментарий предполагает, что он является экспериментальным, и установка «да» может привести к неверным результатам.
Я хотел бы заметить, что я не думаю, что коснулся этого, и установка по умолчанию имеет значение «Да».Я сохранил файл conf.xml из чистой установки, так как я в нем многое изменяю (конечно), глядя на чистую установку, я вижу это:
<xquery enable-java-binding="no" disable-deprecated-functions="no"
enable-query-rewriting="yes" backwardCompatible="no"
enforce-index-use="always"
raise-error-on-failed-retrieval="no">
Я изменил на «Нет» и перезапустил существующий-db.Теперь все работает, как и раньше, у меня теперь нет проблем с поиском, и он возвращает именно то, что я ожидаю, с запросом, написанным точно так же, как в версии 2x.
Итак ... что я думаю, я узнал
Я реализовал новые индексы диапазонов и переиндексировал коллекцию, основываясь на комментариях ниже, и снова включил переписывание запросов.Проверяя monex, я вижу индексы, но в моих запросах они не используются, он сообщает, что индекс - это устаревший «диапазон», а оптимизация - «нет индекса».
Я обнаружил, что не могу этого сделать (подстановочный знак будетделаю, я предполагаю):
($ collection // foo | $ collection // bar) [содержит (., $ фразу)]
или это
($ collection// foo, $ collection // bar) [содержит (., $ фразу)]
или это
$ testnodes: = $ collection // foo |$ collection // bar
затем
$ testnodes [содержит (., $ фразу)]
Хотя он работает, он не использует индекс нового диапазона.Они всегда сообщают, что индекс не используется.
Но для этого используются полностью оптимизированные индексы нового диапазона:
$ collection // foo [содержит (., $ Фразу)] |$ Коллекции // бар [содержит (., $ Фразы)]