将查询部分与 Lucene 和数据库中的部分(MySQL)相结合

Posted

技术标签:

【中文标题】将查询部分与 Lucene 和数据库中的部分(MySQL)相结合【英文标题】:combining a query part with Lucene and part in database (MySQL) 【发布时间】:2012-09-20 15:00:14 【问题描述】:

我有一个应用程序需要过滤并从文章列表中检索结果。对于数据库,我使用 mysql,NHibernate 作为 ORM。该查询还基于关键字进行全文搜索,为此它使用 Lucene.Net。

我的问题是查询跨越“两个”域。例如,我可能需要获取所有包含关键字“交通管制”的文章,并且 PublishedOn

如果我首先在 MySQL 上进行搜索,我不能只得到前 50 个,因为结果可能会在 Lucene 中进一步过滤,我需要 50 作为我的页面大小。如果我从 Lucene.Net 开始,情况也是如此。此外,最好按照“相关性”进行排序,所以这是 Lucene 可以做的事情,而不是 MySQL。

我目前的方法是首先通过 MySQL 过滤,并检索匹配记录的所有主键。然后,我在 Lucene 中进行查询,使用术语查询将主键与结果列表相匹配。但是,Lucene 对于这样的查询非常慢,并且数据库可以包含超过 200,000 篇文章。在 Lucene 中执行这样的查询需要很长时间,而对于全文搜索来说速度非常快。

有什么想法可以解决这样的问题吗?

【问题讨论】:

【参考方案1】:

Lucene 不仅仅是全文搜索。您可以将 PublishedOn 属性添加到 Lucene 文档并执行如下查询:

Text:"traffic control" AND PublishedOn:[00000000 TO 20121001]

查看Lucene syntax documentation 中的“范围搜索”部分。

【讨论】:

这看起来很有趣,我会尽快研究这个。但是,这不会打败拥有 MySQL 数据库的场景吗,因为我认为 MySQL / 传统 RDBMS 更适合此类搜索? Lucene.Net 是否对此类范围搜索执行索引,还是会比 RDBMS 慢得多? 它不会比 RDBMS 慢。 Lucene 和 RDBMS 使用相同的索引算法(B-Tree)。是的,lecene 使用索引来执行范围搜索。 这听起来像是一个很好的解决方案 - 但是我有点困惑何时应该使用 MySQL/RDBMS,以及何时使用 Lucene。如果 lucene 执行相同的索引,并且包含更复杂的全文搜索,那么仅使用 lucene 进行可以包含全文的搜索是否有意义? Karl,我更喜欢将应用程序搜索功能隔离在某种单独的“子系统”中。在 RDBMS 中,您存储应用程序业务逻辑使用的聚合根。在 Lucene 中,您仅存储搜索所需的数据(您可以从聚合根的多个属性中聚合文本)。在我的一个应用程序中,我决定将搜索功能分成两个模块:全文搜索模块和按过滤器模块搜索(很多应用程序都这样做,例如 RedMine)。另一种方法是改用文档数据库,看看ravendb.net

以上是关于将查询部分与 Lucene 和数据库中的部分(MySQL)相结合的主要内容,如果未能解决你的问题,请参考以下文章

Lucene Index Search

lucene 查询部分字段总是返回 null

学习 Lucene 原来可以那么简单!

lucene

荧客技荐学习 Lucene 原来可以那么简单!

ssm学习——Lucene建立索引