【问题标题】:How to use Sphinx BuildExcerpts如何使用 Sphinx BuildExcerpts
【发布时间】:2012-02-07 19:46:32
【问题描述】:

所以,我已经设置了一个 Sphinx 配置文件。我有一个非常简单的模式,有两个字段,标题和正文,其中标题是小说的名称,正文是完整的小说本身。为了简单起见,我只添加了一本小说。索引器工作得很好,Python API 使查询 sphinxd 变得轻而易举。到目前为止,我真的印象深刻,这似乎是我迄今为止研究过的最容易设置的全文搜索引擎(比 Lucene 或 Solr 容易得多,比 Woosh 更快)。

我已跳过任何数据库后端。我的小说是纯 .txt 格式的,我添加了 使用这个简单的 xml 示例(通过 xmlpipe)

<?xml version="1.0" encoding="utf-8"?>
<sphinx:docset>
       <sphinx:document id="1">
             <title><![CDATA[Dan Simmons - I Canti di Hyperion 3 - Endymion]]></title>
             <body><![CDATA[ * ALL THE NOVEL HERE * ]]></body>
       </sphinx:document>
</sphinx:docset>

顺便说一句,我在档案中搜索“tartaruga”,它是意大利语的“turtle”,我确定这个词就是文件。事实上,被找到了 3 次,我猜这就是 Sphinx 给我的回报 ('hits': 3)。这是完整的结果:

{'attrs': [],
'error': '',
'fields': ['title', 'body'],
'matches': [{'attrs': {}, 'id': 1, 'weight': 1}],
'status': 0,
'time': '0.392',
'total': 1,
'total_found': 1,
'warning': '',
'words': [{'docs': 1, 'hits': 3, 'word': 'tartaruga'}]}

我想要的,最终是这样的:

[
  {
    'title': 'Dan Simmons - I Canti di Hyperion 3 - Endymion',
    'body': 'il vecchio mostrò quel suo sorriso a becco di tartaruga. — non bisogna dimenticare il palazzo dello shrike, né il nostro vecchio amico shrike, giusto? non ce ne sono altre?'
  },
  {
    'title': 'Dan Simmons - I Canti di Hyperion 3 - Endymion',
    'body': '— vieni più vicino, raul endymion. — la voce pareva il rumore di una lama spuntata che sfregasse su pergamena. le labbra si muovevano come il becco d\'una tartaruga.'
  },
  {
    'title': 'Dan Simmons - I Canti di Hyperion 3 - Endymion',
    'body': 'il becco di tartaruga ebbe una contrazione, la grossa testa si mosse in un cenno d\'assenso. notai ora che il viso del vecchio, malgrado i danni provocati dai secoli, aveva ancora tratti netti e spigolosi... un\'aria da satiro.'
  },
]

我的意思是,摘录的书和上下文中的单词出现的数组(我已经选择了句子,但是匹配之前或之后的 n 个单词会起作用)。我想我必须使用 BuildExcerpts,但是如何使用?

另外,如果我想同时匹配 tartaruga(乌龟)和 tartarughe(乌龟),我想发出类似 tartarug* 的查询。如何做到这一点是狮身人面像?提前致谢。

【问题讨论】:

  • 我知道 PHP API 有 BuildExceprts 可以做到这一点,你可以在这里找到一个例子:sphinxsearch.com/wiki/… 我不确定 python API 是否有同样的
  • hmmm,这是否意味着如果我有来自 100 本书的 100 个匹配项,我必须在内存中加载 100 部小说?
  • 是的。您需要加载文本,然后将其发送到 sphinx 以构建摘录。

标签: python full-text-search sphinx


【解决方案1】:

我为我正在从事的项目做同样的事情。我的建议是,将整本书作为一个字段加载并不是一个好主意,除非您只打算使用一本书,而不是多本书。这是我的做法。

  1. 书籍一次一页地存储在 MySQL 数据库中。
  2. 在包含数百万页文本的数据库中运行 sphinx - 运行速度非常快,返回带有您正在查找的文本的每一页(或者取决于数据库中的页数,只需获取前 30 个或其他)。
  3. 使用摘录生成器从页面中获取摘录,然后突出显示搜索阶段。
  4. 如果 Python 无法访问摘录生成器(可能仅限 php),那么您可以使用正则表达式轻松完成相同的工作 - 您只需找到您的搜索短语并执行正则表达式即可在两边找到这么多文本,以及另一个添加突出显示的正则表达式。

您可以编写一个 python 脚本(我使用从 bash shell 运行的 PHP 脚本)来一次提取一页文本,对其进行清理,然后将其添加到数据库中。

您需要一个至少包含两个类似表的数据库

books (fields could be called, id, name, author)

pages (fields would be id, book_id, page_text)

Sphinx 会返回一个页面 id,然后你使用一个简单的查询从 MySQL 获取页面...

SELECT page_text FROM pages WHERE id = $idreturnedbysphinx;

然后您将返回的文本发送到文本摘录器/文本荧光笔。

Sphinx 可以搜索确切的词或词干(以及更多),但您需要在 sphinx.conf 文件中进行设置。

您至少需要两个索引定义:

indexer indexname1
{
     #source database connection and sql query
      source                = src1
      path                  = /var/data/indexname1
     [... other settings ...]
     #make sure stemming is switched off
     morphology             = none


}
#child index inherits the above, and add stemming
index indexname1stemmed : indexname1
{
    path            = /var/data/indexname1stemmed
    morphology      = stem_en
    index_exact_words   = 1
}

然后,您还需要在 sphinx 搜索中指定要使用的匹配模式。我不知道 python 语法,但是 sphinx 手册比我做得更好: http://sphinxsearch.com/docs/current.html#matching-modes

您可以在没有 SQL 数据库的情况下完成所有这些操作并将其保存在文本文件中,但我可能会使用每页一个文本文件作为一种更易于管理的工作方式,否则您将返回整个电子书作为您的搜索结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 2011-04-18
    相关资源
    最近更新 更多