Lucene 索引升级存在问题db版本2到4.5

Lucene 索引升级存在问题db版本2到4.5,lucene,xquery,exist-db,Lucene,Xquery,Exist Db,我正在升级和测试一个大型安装,遇到了一个我无法理解的问题。我有一个很大的文档集合,其中我的索引创建如下: <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 defaul

我正在升级和测试一个大型安装,遇到了一个我无法理解的问题。我有一个很大的文档集合,其中我的索引创建如下:

<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>
收益率:

您可以看到,与前面的示例不同,没有“heart”的h1不会返回

升级时我错过了什么?我错过或不明白Lucene有什么变化吗

更新 作为一名黑客(IMHO),这是有效的:

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>
        )]
更新四 我将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>
我得到了完全相同的结果

更新V 我想我是在划船。本周末将再次运行整个过程,删除所有内容并重试,但这毫无意义,也不起作用

更新VI 我不喜欢玩平底船!现在,在查看结果时,基本上是在当前安装中执行此搜索:

 for $hit in collection(xmldb:encode-uri($collection))//*[ft:query(.,
        <query>
            <phrase>{$phrase}</phrase>
        </query>
        )]
这向我表明,如果您安装了不同的应用程序,则导出数据库然后重新导入将无法工作

不幸的是,我不得不下注,寻找替代方案。我可以尝试重建数据或其他东西,但该应用程序有10000个用户。无法重新创建

在这个时候,我只能说它还没有准备好进入黄金时段,将只是坐在运行良好的旧数据库上,多年来一直如此

只是要注意。。。在安装了新的、干净的数据库并且并没有任何更改之后,我可以访问Monex或dashboard。如果我从备份中导入(因为它不兼容二进制文件,所以需要导入),则所有备份都会中断

对于开发人员来说,这是一个显而易见的问题

再次更新 我做了一个完全干净的安装。之后,我可以访问Monex,没有任何问题。然后我恢复我的数据库。注意:在完成的那一刻,有一个问题问我是否希望升级应用程序。不确定答案是否正确,也许这是一个问题,而我的答案是错误的(我的答案是否定的)

在重新安装之后,我可以很好地使用DB和我的整个应用程序。但在尝试运行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>
与:

collection(xmldb:encode-uri($collection))//*
所以。。。所有这些。。。解决方案是for循环需要:

for $hit in (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
    <query>
        <phrase>{$phrase}</phrase>
    </query>
    )]
一秒钟,回答正确

for $hit in (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
17秒,回答正确

for $hit in (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
4.5版:

for $hit in collection(xmldb:encode-uri($collection))//*[ft:query(.,
for $hit in collection(xmldb:encode-uri($collection))//*[ft:query(.,
10秒,回答完全错误(返回div和未命中)

一秒钟,回答正确

在我看来,在旧的eXist中,查询没有返回任何内容,而在这个新的eXist中,似乎会为发送的每个元素返回一个结果,如果不存在索引,它仍然会返回它

最后一次更新 在查看干净的安装
conf.xml
时,我在xquery条目中找到了
启用查询重写
的注释。这一评论表明它是实验性的,设置为“是”可能会导致错误的结果

我想指出的是,我不相信我碰过这个,默认安装将这个值设置为“是”。我从clean安装中保存了conf.xml,因为我在其中更改了很多内容(当然),在查看clean安装时,我看到了以下内容:

<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">

我改为“否”,重新启动了exist db。现在一切都和以前一样工作了,我现在在搜索中没有问题了,它返回了我所期望的结果,查询的编写与2x版完全相同

所以我相信我学到了什么 我实现了新的范围索引,并根据下面的注释重新索引集合,并重新启用了查询重写。检查monex我看到了索引,但我的查询没有使用它们,它将索引报告为遗留的“范围”,将优化报告为“无索引”

我发现我不能这样做(我假设通配符会这样做):

($collection//foo |$collection//bar)[包含(,$phrase)]

还是这个

($collection//foo,$collection//bar)[包含(,$phrase)]

还是这个

$testnodes:=$collection//foo |$collection//bar

然后

$testnodes[包含(,$phrase)]

虽然有效,但它不使用新的范围索引。它们总是报告没有使用索引

但这确实使用了完全优化的新范围索引:


$collection//foo[contains(,$phrase)]|$collection//bar[contains(,$phrase)]

我们应该先清除错误

  • 空白分析器的类应该是
    org.apache.lucene.analysis.core.WhitespaceAnalyzer
  • 虽然它看起来不像是通过它的“id”引用空白分析器,所以您可以删除它

  • 您使用
    标准分析器的配置在我看来是错误的。您指定了一个
    stopwords
    参数,但是:
  • 它的类是错误的,应该是
    org.apache.lucene.analysis.util。字符集
    ,以及
  • 您没有给它任何值
  • 如果只需要默认的停止字,可以完全忽略该参数

    完成这些更改后,应尝试重新索引并再次监视日志

    之后,您应该使用eXist 4.5.0中仪表板上的Monex应用程序检查可用索引,以检查您的数据是否按预期编制了索引

    更新1 来自@kevin brown的评论:

    从我今天看到的情况来看,如果我这样做($collection//foo |$collection//bar)[fn:contains(,'string')],就不会使用索引。但是,如果我执行这个$collection//foo[fn:contains(,'string')]|$collection//bar[fn:contains(,'string')],将使用新的范围索引,并且优化已满

    我可以确认,在XQuery的某些公式中,eXist db没有正确地优化查询以利用范围索引。这肯定是一个错误

    eXist db的Java Admin客户端允许您显示查询的跟踪:

  • ($collection//foo |$collection//bar)[fn:contains(,$string)]
    Kevin报告没有使用索引,生成跟踪:

    $collection/descendant::{}foo union
        $collection/descendant::{}bar
            [contains(self::node(), $string)]
    
    $collection
    (# exist:optimize-field #)
    (# exist:optimize #) {
        descendant::{}foo[range:contains(self::node(), $string)]
    }
    union $collection
    (# exist:optimize-field #)
    (# exist:optimize #) {
        descendant::{}bar[range:contains(self::node(), $string)]
    }
    
  • $collection//foo[fn:contains(,$string)
    
    for $hit in (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
        <query>
            <phrase>{$phrase}</phrase>
        </query>
        )]
    
    for $hit in collection(xmldb:encode-uri($collection))//*[ft:query(.,
    
    for $hit in (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
    
    for $hit in collection(xmldb:encode-uri($collection))//*[ft:query(.,
    
    for $hit in (collection(xmldb:encode-uri($collection))//*)[ft:query(.,
    
    <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">
    
    $collection/descendant::{}foo union
        $collection/descendant::{}bar
            [contains(self::node(), $string)]
    
    $collection
    (# exist:optimize-field #)
    (# exist:optimize #) {
        descendant::{}foo[range:contains(self::node(), $string)]
    }
    union $collection
    (# exist:optimize-field #)
    (# exist:optimize #) {
        descendant::{}bar[range:contains(self::node(), $string)]
    }
    
    let $coll := collection(xmldb:encode-uri($collection))
    
    let target := $coll//p | $coll//h1 | $coll//h2 | $coll//h3 | $coll//li
    
     <ignore qname="div"/>
    
    <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"  
            xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <fulltext default="none" attributes="false"/>
        <range>
           <create qname="mods:p" type="xs:string"/>
           <create qname="mods:li" type="xs:string"/>
           <create qname="mods:h1" type="xs:string"/>
           <create qname="mods:h2" type="xs:string"/>
           <create qname="mods:h3" type="xs:string"/>
        </range>
        <lucene>
            <analyzer class="org.apache.lucene.analysis.standard.StandardAnalyzer"/>
            <text qname="mods:p"/>
            <text qname="mods:li"/>
            <text qname="mods:h1"/>
            <text qname="mods:h2"/>
            <text qname="mods:h3"/>
            <ignore qname="mods:div"/>
        </lucene>
      </index>
    </collection>