我正在建设一个Django网站,我正在寻找一个搜索引擎。

一些候选人:

Lucene/Lucene with Compass/Solr 斯芬克斯 Postgresql内置全文搜索 MySQl内置全文搜索

选择标准:

结果相关性和排名 搜索和索引速度 易于使用,易于与Django集成 资源需求——站点将托管在VPS上,所以理想情况下搜索引擎不需要大量的RAM和CPU 可伸缩性 额外的功能,如“你的意思是?”,相关搜索等

任何使用过上述搜索引擎或其他不在列表中的引擎的人——我很想听听你的意见。

编辑:至于索引需求,由于用户不断地向站点输入数据,这些数据将需要不断地进行索引。它不必是实时的,但理想情况下,新数据在索引中显示的延迟不超过15 - 30分钟


当前回答

这是我对这个老问题的看法。我强烈推荐你看看ElasticSearch。

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式的、支持多租户的全文搜索引擎,具有RESTful web界面和无模式的JSON文档。Elasticsearch是用Java开发的,在Apache许可证的条款下作为开源发布。

相对于其他FTS(全文搜索)引擎的优势是:

rest式接口 更好的可伸缩性 大型社区 由Lucene构建 开发人员 丰富的文档 有很多开放源码库可用(包括Django)

我们在我们的项目中使用这个搜索引擎,并且非常满意。

其他回答

很高兴看到有人插话谈论Lucene——因为我对此一无所知。

而斯芬克斯,我很了解,所以看看我能不能帮上忙。

Result relevance ranking is the default. You can set up your own sorting should you wish, and give specific fields higher weightings. Indexing speed is super-fast, because it talks directly to the database. Any slowness will come from complex SQL queries and un-indexed foreign keys and other such problems. I've never noticed any slowness in searching either. I'm a Rails guy, so I've no idea how easy it is to implement with Django. There is a Python API that comes with the Sphinx source though. The search service daemon (searchd) is pretty low on memory usage - and you can set limits on how much memory the indexer process uses too. Scalability is where my knowledge is more sketchy - but it's easy enough to copy index files to multiple machines and run several searchd daemons. The general impression I get from others though is that it's pretty damn good under high load, so scaling it out across multiple machines isn't something that needs to be dealt with. There's no support for 'did-you-mean', etc - although these can be done with other tools easily enough. Sphinx does stem words though using dictionaries, so 'driving' and 'drive' (for example) would be considered the same in searches. Sphinx doesn't allow partial index updates for field data though. The common approach to this is to maintain a delta index with all the recent changes, and re-index this after every change (and those new results appear within a second or two). Because of the small amount of data, this can take a matter of seconds. You will still need to re-index the main dataset regularly though (although how regularly depends on the volatility of your data - every day? every hour?). The fast indexing speeds keep this all pretty painless though.

我不知道这是否适用于您的情况,但Evan Weaver比较了一些常见的Rails搜索选项(Sphinx, Ferret (Lucene的Ruby移植)和Solr),运行了一些基准测试。我想可能有用。

我还没有深入研究MySQL的全文搜索,但我知道它在速度和功能方面都无法与Sphinx、Lucene或Solr竞争。

SearchTools-Avi说:“MySQL文本搜索,它甚至不能索引三个字母或更少的单词。”

从MySQL 5.0开始,MySQL全文的最小字长是可调的。谷歌'mysql全文最小长度'简单的指令。

也就是说,MySQL全文文本有局限性:首先,一旦你达到一百万左右的记录,它就会变得很慢,……

我会把mnoGoSearch添加到列表中。非常高性能和灵活的解决方案,它作为谷歌:索引器从多个站点获取数据,您可以使用基本标准,或发明自己的钩子,以获得最大的搜索质量。它还可以直接从数据库中获取数据。

这个解决方案今天还不太为人所知,但它满足了最大的需求。你可以编译并安装它,或者在独立的服务器上,甚至在你的主服务器上,它不需要像Solr那样多的资源,因为它是用C编写的,即使在小型服务器上也能完美运行。

一开始你需要自己编译,所以需要一些知识。我为Debian做了一个小脚本,可能会有帮助。欢迎任何调整。

当你使用Django框架时,你可以在中间使用PHP客户端,或者在Python中找到解决方案,我看到了一些文章。

当然,mnoGoSearch是开源的,GNU GPL。

我们刚刚从Elasticsearch切换到Postgres Full Text。因为我们已经使用了Postgres,所以我们现在省去了保持索引更新的麻烦。 但这只影响全文搜索。然而,在某些用例中,Elasicsearch明显更好。也许是面或类似的东西。

Apache Solr


除了回答OP的问题,让我从简单的介绍到详细的安装和实现,介绍一些关于Apache Solr的见解。

简单介绍


任何有以上搜索引擎经验的人,或其他 引擎不在列表中——我很想听听你的意见。

Solr不应该用于解决实时问题。对于搜索引擎来说,Solr几乎就是一场游戏,而且工作完美无缺。

Solr在高流量的web应用程序上工作得很好(我在某个地方读到过,它不适合这种情况,但我支持这种说法)。它利用的是RAM,而不是CPU。

结果相关性和排名

这种提升可以帮助你把你的结果排在最上面。假设,您试图在字段firstname和lastname中搜索一个名字john,并且您希望给firstname字段提供相关性,那么您需要增强firstname字段,如图所示。

http://localhost:8983/solr/collection1/select?q=firstname:john^2&lastname:john

如您所见,firstname字段的分数提高到了2。

更多关于solrrelevance

搜索和索引速度

速度快得令人难以置信,在这一点上没有妥协。我搬到索尔的原因。

关于索引速度,Solr还可以处理数据库表中的join。更高更复杂的JOIN确实会影响索引速度。然而,一个巨大的RAM配置可以很容易地解决这种情况。

RAM越大,Solr的索引速度越快。

易于使用,易于与Django集成

从来没有尝试过集成Solr和Django,但是你可以通过Haystack实现这一点。我在这个网站上找到了一些有趣的文章,这是它的github。

资源需求——站点将托管在VPS上,所以理想情况下搜索引擎不需要大量的RAM和CPU

Solr在RAM上繁殖,所以如果RAM很高,你不必担心Solr。

如果您有数十亿条记录,那么Solr的RAM使用量在全索引时就会激增,您可以聪明地使用Delta导入来解决这种情况。如前所述,Solr只是一个接近实时的解决方案。

可伸缩性

Solr是高度可伸缩的。在SolrCloud上看看。 它的一些关键特性。

碎片(或者分片是在多台机器上分配索引的概念,比如如果您的索引变得太大) 负载平衡(如果Solrj与Solr云一起使用,它会自动使用Round-Robin机制来处理负载平衡) 分布式搜索 高可用性

额外的功能,如“你的意思是?”,相关搜索等

对于上面的场景,您可以使用Solr中打包的SpellCheckComponent。还有很多其他特性,The SnowballPorterFilterFactory帮助检索记录,如果你输入,books而不是book,你会显示与book相关的结果。


这个答案主要集中在Apache Solr和MySQL上。Django超出了范围。

假设您在LINUX环境下,您可以继续阅读本文。(我用的是Ubuntu 14.04版本)

详细的安装

开始

从这里下载Apache Solr。也就是4.8.1版本。你可以下载新版本,我觉得这个很稳定。

下载存档后,将其解压缩到您选择的文件夹中。 说. .下载或其他。所以它看起来像Downloads/solr-4.8.1/

听你的提示…在目录内导航

shankar@shankar-联想: cd 下载/solr-4.8.1

所以现在你在这里…

shankar@shankar联想: ~/下载/solr-4.8.1$

启动Jetty应用程序服务器

Jetty可以在solr-4.8.1目录的examples文件夹中使用,因此在该文件夹中导航并启动Jetty Application Server。

shankar@shankar-lenovo:~/Downloads/solr-4.8.1/example$ java -jar start.jar

现在,不要关闭终端,最小化它,让它留在一边。

提示:在start.jar后使用&使Jetty Server在 背景)

要检查Apache Solr是否成功运行,请在浏览器上访问这个URL。http://localhost:8983/solr

在自定义端口上运行Jetty

它默认运行在8983端口上。您可以在这里或直接在jetty.xml文件中更改端口。

java -Djetty。Port =9091 -jar start.jar

下载JConnector

这个JAR文件作为MySQL和JDBC之间的桥梁,在这里下载平台独立版本

下载后,解压文件夹并复制mymysql -connector-java-5.1.31-bin.jar并粘贴到lib目录。

shankar@shankar-lenovo:~/Downloads/solr-4.8.1/contrib/dataimporthandler/lib

创建要链接到Apache Solr的MySQL表

要使用Solr,需要搜索一些表和数据。为此,我们将使用MySQL创建一个表,并推送一些随机名称,然后我们可以使用Solr连接到MySQL,并索引该表及其条目。

1.表结构

CREATE TABLE test_solr_mysql
 (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(45) NULL,
  created TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
 );

2.填充上面的表

INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jean');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jack');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jason');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Vego');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Grunt');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jasper');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Fred');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jenna');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Rebecca');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Roland');

进入核心并添加lib指令

1.导航到

shankar@shankar-lenovo: ~/Downloads/solr-4.8.1/example/solr/collection1/conf

2.修改“solrconfig.xml”文件

将这两个指令添加到这个文件中。

  <lib dir="../../../contrib/dataimporthandler/lib/" regex=".*\.jar" />
  <lib dir="../../../dist/" regex="solr-dataimporthandler-\d.*\.jar" />

现在添加DIH(数据导入处理程序)

<requestHandler name="/dataimport" 
  class="org.apache.solr.handler.dataimport.DataImportHandler" >
    <lst name="defaults">
      <str name="config">db-data-config.xml</str>
    </lst>
</requestHandler>

3.创建db-data-config.xml文件

如果文件存在,则忽略,将这些行添加到该文件中。正如第一行所示,您需要提供MySQL数据库的凭据。数据库名、用户名和密码。

<dataConfig>
    <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/yourdbname" user="dbuser" password="dbpass"/>
    <document>
   <entity name="test_solr" query="select CONCAT('test_solr-',id) as rid,name from test_solr_mysql WHERE '${dataimporter.request.clean}' != 'false'
      OR `created` > '${dataimporter.last_index_time}'" >
    <field name="id" column="rid" />
    <field name="solr_name" column="name" />
    </entity>
   </document>
</dataConfig>

(提示:你可以有任何数量的实体,但要注意id字段, 如果它们是相同的,那么索引将被跳过。)

4.修改schema.xml文件

将其添加到您的schema.xml中,如下所示..

<uniqueKey>id</uniqueKey>
<field name="solr_name" type="string" indexed="true" stored="true" />

实现

索引

这才是真正的交易。为了使用Solr查询,您需要将数据从MySQL索引到Solr。

步骤1:进入Solr管理面板

在浏览器上点击URL http://localhost:8983/solr。屏幕像这样打开。

如标记所示,转到日志记录,以检查上述配置是否导致错误。

步骤2:检查日志

好的,现在你在这里,正如你所能看到的,有很多黄色的信息(警告)。确保没有用红色标记的错误消息。之前,在我们的配置中,我们在db-data-config.xml上添加了一个选择查询,如果该查询上有任何错误,它就会显示在这里。

很好,没有错误。我们准备好了。让我们从列表中选择collection1,并选择Dataimport

步骤3:DIH(数据导入处理程序)

使用DIH,您将通过配置文件db-data-config.xml从Solr接口连接到MySQL,并从数据库检索到Solr索引的10条记录。

为此,选择完全导入,并选中“清洁”和“提交”选项。现在,如图所示单击Execute。

或者,您也可以使用这样的直接全导入查询。

http://localhost:8983/solr/collection1/dataimport?command=full-import&commit=true

在单击Execute之后,Solr开始索引记录,如果有任何错误,它会说索引失败,您必须回到Logging部分查看哪里出了问题。

假设此配置没有错误,且索引已成功完成。,你会收到这个通知。

步骤4:运行Solr查询

看起来一切都很顺利,现在您可以使用Solr Queries查询被索引的数据了。单击左侧的查询,然后按下底部的执行按钮。

您将看到索引记录,如所示。

对应的列出所有记录的Solr查询是

http://localhost:8983/solr/collection1/select?q=*:*&wt=json&indent=true

好了,这就是所有10条索引记录。例如,我们只需要以Ja开头的名称,在这种情况下,您需要以列名solr_name为目标,因此您的查询如下所示。

http://localhost:8983/solr/collection1/select?q=solr_name:Ja*&wt=json&indent=true

这就是编写Solr查询的方法。想了解更多,请看这篇漂亮的文章。