exist-db 中的 XQuery 模糊搜索

XQuery fuzzy search in exist-db

我们使用 exist-db 库来存储各种 xml 文档,我们使用 xquery 在这些文档上执行搜索。这是 xml 文档的示例:

<person personID="some_id">
    <name>
        <familyName>Doe</familyName>
        <firstName>John</firstName>
    </name>
</person>

我们使用的搜索是模糊搜索,查询格式如下

xquery version "3.0";
for $doc in collection('/db/Persons')/*[ft:query(.,'milan~')] 
let $score := ft:score($doc) 
order by $score descending return base-uri($doc)

问题是搜索命令的结果比较奇怪。例如Milun, Milun, Golan, Vilon排在Milan之前。换句话说,与完全匹配 ( Milan ) 相比,搜索为不完全匹配的结果分配更高的分数。我们做错了什么?与接近精确匹配相比,精确匹配有没有办法获得更高的分数?

eXist-db 的全文搜索索引建立在Apache Lucene. This problem was reported in the Lucene bug tracker (see https://issues.apache.org/jira/browse/LUCENE-329) and other products built on it, like ElasticSearch (see https://github.com/elastic/elasticsearch/issues/20369), and a fix was made in Lucene 5.3 with https://svn.apache.org/viewvc?view=revision&revision=1680548 之上。

为了让 eXist 从这一改进中受益,eXist 需要将其 Lucene 库从当前版本的 eXist Lucene 4.10.4 升级到 Lucene 5.3 或更高版本。 Lucene 4.x 和 5.x+ 之间的一些 API 不兼容性到目前为止阻止了 eXist 进行这种跳跃(参见未解决的问题 https://github.com/eXist-db/exist/issues/1160),但我相信挑战不是不可逾越。

同时,作为一种解决方法,您可以添加一个额外的查询来查找完全匹配,并且 returns 仅此或作为模糊匹配上方的第一个命中。根据您的应用程序,您可能需要从用户提供的输入中删除波浪号,但这应该可以实现您的目标。