开源搜索引擎工具

搜索引擎工具

graph TB A((Lucene)) A --> B[Solr] A --> C[ElasticSearch] A --> H[Java] B --> D[RESTful & Admin] B --> E[Core & Field] B --> F[IKAnalyzer] C --> F C --> G[Kibana]

[TOC]

Lucene

Lucene ([‘lu:si:n]) 是基于 java 的开源全文索引工具包

本文内容源自 how2j

示例代码:

// 1. 准备中文分词器
IKAnalyzer analyzer = new IKAnalyzer();

// 2. 使用测试数据创建索引
List<String> productNames = new ArrayList<>();
productNames.add("飞利浦led灯泡e27螺口暖白球泡灯家用照明超亮节能灯泡转色温灯泡");
productNames.add("飞利浦led灯泡e14螺口蜡烛灯泡3W尖泡拉尾节能灯泡暖黄光源Lamp");
productNames.add("雷士照明 LED灯泡 e27大螺口节能灯3W球泡灯 Lamp led节能灯泡");
productNames.add("飞利浦 led灯泡 e27螺口家用3w暖白球泡灯节能灯5W灯泡LED单灯7w");
productNames.add("飞利浦led小球泡e14螺口4.5w透明款led节能灯泡照明光源lamp单灯");
productNames.add("飞利浦蒲公英护眼台灯工作学习阅读节能灯具30508带光源");
productNames.add("欧普照明led灯泡蜡烛节能灯泡e14螺口球泡灯超亮照明单灯光源");
productNames.add("欧普照明led灯泡节能灯泡超亮光源e14e27螺旋螺口小球泡暖黄家用");
productNames.add("聚欧普照明led灯泡节能灯泡e27螺口球泡家用led照明单灯超亮光源");		
// Directory index = createIndex(analyzer, productNames);
Directory index = new RAMDirectory();
IndexWriterConfig config = new IndexWriterConfig(analyzer);
IndexWriter writer = new IndexWriter(index, config);

for (String name : productNames) {
    Document doc = new Document();
    doc.add(new TextField("name", name, Field.Store.YES));
    writer.addDocument(doc);
}
writer.close();

// 3. 查询器
String keyword = "护眼带光源";
Query query = new QueryParser("name", analyzer).parse(keyword);

// 4. 搜索
IndexReader reader = DirectoryReader.open(index);
IndexSearcher searcher = new IndexSearcher(reader);
int numberPerPage = 1000;
System.out.printf("当前一共有%d条数据%n",productNames.size());
System.out.printf("查询关键字是:\"%s\"%n",keyword);
System.out.printf("查询字符串分词结果:\"%s\"%n",query);
ScoreDoc[] hits = searcher.search(query, numberPerPage).scoreDocs;

// 5. 显示查询结果 
for (int i = 0; i < hits.length; ++i) {
    ScoreDoc scoreDoc= hits[i];
    int docId = scoreDoc.doc;
    Document d = searcher.doc(docId);
    List<IndexableField> fields = d.getFields();
    System.out.print((i + 1));
    System.out.print("\t" + scoreDoc.score);
    for (IndexableField f : fields) {
        System.out.print("\t" + d.get(f.name()));
    }
    System.out.println();
}
// 6. 关闭查询
reader.close();

执行结果 1:

查询关键字是:"护眼带光源"
查询字符串分词结果:"name:护眼 name:带 name:光源"
1	5.159822	飞利浦蒲公英护眼台灯工作学习阅读节能灯具30508带光源
2	0.43331528	欧普照明led灯泡蜡烛节能灯泡e14螺口球泡灯超亮照明单灯光源
3	0.425806	飞利浦led灯泡e14螺口蜡烛灯泡3W尖泡拉尾节能灯泡暖黄光源Lamp
4	0.425806	飞利浦led小球泡e14螺口4.5w透明款led节能灯泡照明光源lamp单灯
5	0.425806	欧普照明led灯泡节能灯泡超亮光源e14e27螺旋螺口小球泡暖黄家用
6	0.425806	聚欧普照明led灯泡节能灯泡e27螺口球泡家用led照明单灯超亮光源

执行结果 2:

查询关键字是:"led 黄色"
查询字符串分词结果:"name:led name:黄色"
1	0.22168216	飞利浦led小球泡e14螺口4.5w透明款led节能灯泡照明光源lamp单灯
2	0.22168216	聚欧普照明led灯泡节能灯泡e27螺口球泡家用led照明单灯超亮光源
3	0.21906272	雷士照明 LED灯泡 e27大螺口节能灯3W球泡灯 Lamp led节能灯泡
4	0.20684227	飞利浦 led灯泡 e27螺口家用3w暖白球泡灯节能灯5W灯泡LED单灯7w
5	0.1634743	飞利浦led灯泡e27螺口暖白球泡灯家用照明超亮节能灯泡转色温灯泡
6	0.1634743	欧普照明led灯泡蜡烛节能灯泡e14螺口球泡灯超亮照明单灯光源
7	0.16064131	飞利浦led灯泡e14螺口蜡烛灯泡3W尖泡拉尾节能灯泡暖黄光源Lamp
8	0.16064131	欧普照明led灯泡节能灯泡超亮光源e14e27螺旋螺口小球泡暖黄家用

执行结果 3:

查询关键字是:"led 黄"
查询字符串分词结果:"name:led name:黄"
1	2.0358434	欧普照明led灯泡节能灯泡超亮光源e14e27螺旋螺口小球泡暖黄家用
2	0.22168216	飞利浦led小球泡e14螺口4.5w透明款led节能灯泡照明光源lamp单灯
3	0.22168216	聚欧普照明led灯泡节能灯泡e27螺口球泡家用led照明单灯超亮光源
4	0.21906272	雷士照明 LED灯泡 e27大螺口节能灯3W球泡灯 Lamp led节能灯泡
5	0.20684227	飞利浦 led灯泡 e27螺口家用3w暖白球泡灯节能灯5W灯泡LED单灯7w
6	0.1634743	飞利浦led灯泡e27螺口暖白球泡灯家用照明超亮节能灯泡转色温灯泡
7	0.1634743	欧普照明led灯泡蜡烛节能灯泡e14螺口球泡灯超亮照明单灯光源
8	0.16064131	飞利浦led灯泡e14螺口蜡烛灯泡3W尖泡拉尾节能灯泡暖黄光源Lamp

仔细查看执行结果 2 和 3,这两次搜索意图其实很相近,但 Lucene 却返回了完全不同的结果。实际的搜索引擎会考虑用户的搜索意图,例如自动修改用户查询字符串以获得语义(意图)相似的查询字符串然后进行查询,最后向用户展示综合后的查询结果

Solr

Solr ([‘s?ul?])是一个开源搜索平台,用于构建搜索应用程序。它建立在 Lucene (全文搜索引擎)之上

Solr 提供了类似 RESTful-API 的方式以便于其他系统与 Solr 进行通信,同时 Solr 提供了 web Admin 界面,便于用户操作与管理

IKAnalyzer

默认的 Solr 安装包不包含中文分词器,此时 Solr 会将中文语句、段落或者文章分解为一个个单字,无法实现中文词语检索。IKAnalyzer 是一个三方中文分词器

“研究生命科学” 为例,使用默认的 Solr 分词器,分词结果为 6 个独立的汉字:

研 | 究 | 生 | 命 | 科 | 学

使用 IKAnalyzer 作为分词器,分词结果为 5 个汉语单词:

研究生 | 研究 | 生命科学 | 生命 | 科学

概念

  • Core

    如果说 Solr 相当于一个数据库的话,那么 Core 就相当于一张表

  • Field,查询时需要指定字段名

    Core 相当于表,接下来就要为这个表设置字段,用于存放数据。使用 Solr 进行查询时需要指明查找的字段与查询的词,例如:SolrUtil.query("name:小米 电视 平板",0,10)SolrUtil.query("category:家电",0,10)

常用命令(windows)

  • solr.cmd start
  • solr.cmd stop -all
  • solr.cmd create -c how2java -p 8983,创建 core
  • solr.cmd delete -c core1

ElasticSearch

和 Solr 一样, ElasticSearch 基于 Lucene,提供了更为便利的访问和调用

ES 和 Solr 一样没有默认的中文分词器,需要三方工具,安装命令:

elasticsearch-plugin.bat install file:.\elasticsearch-analysis-ik-6.2.2.zip

Kibana

Kibana 是一个开源的分析和可视化平台,设计用于和 Elasticsearch 一起工作。Kibana 是分析 ES 中数据的工具,Kibana 提供了 Dev tools 工具,便于用户使用 RESTful 风格方式向 ES 服务发送请求

默认访问端口:127.0.0.1:5601

索引

索引相当于就是一个数据库服务器上的某个数据库,所以索引也可以看成是 Elastic Search 里的某个数据库

使用 RESTful 风格操控 ES

PUT /how2java?pretty ,添加索引  
GET /_cat/indices?v ,查询  
DELETE /how2java?pretty , 删除

// 向 product 中插入一条数据
PUT /how2java/product/1?pretty
{
  "name": "蜡烛"
}
相关文章
相关标签/搜索