热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Elasticsearch全文检索:根据关键词对全文查询检索,关键词也分词处理

之前看过了solr的全文检索工具,原理比较简单,理解起来也快;这次我们项目上要求用Elasticsearch实现全文检索,据说这个插件功能更厉害,但是也没有具体研究过;这里就省略了es的部署过

之前看过了solr的全文检索工具,原理比较简单,理解起来也快;这次我们项目上要求用Elasticsearch实现全文检索,据说这个插件功能更厉害,但是也没有具体研究过;这里就省略了es的部署过程和集成springboot的方法了,直接附上我的后台查询代码;


import com.pridecn.file.domain.EsFileInfo;
import com.pridecn.file.service.ElasticsearchService;
import io.searchbox.client.JestClient;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
public class ElasticsearchServiceImpl implements ElasticsearchService {
@Autowired
JestClient jestClient;
@Override
public List findPublishedFileByKeyWord(String keyWord, int pageNum, int pageSize) {
//处理特殊字符
keyWord = QueryParser.escape(keyWord);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.boolQuery()
.should(/*QueryBuilders.queryStringQuery(keyWord).field("FILE_NAME")*/QueryBuilders.matchQuery("FILE_NAME",keyWord).analyzer("ik_smart"))
.should(/*QueryBuilders.queryStringQuery(keyWord).field("attachment.content")*/QueryBuilders.matchQuery("attachment.content",keyWord).analyzer("ik_smart")));
//初始化高亮对象
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("FILE_NAME");//高亮title
highlightBuilder.field("attachment.content");
highlightBuilder.preTags("").postTags("");//高亮标签
//设置高亮
searchSourceBuilder.highlighter(highlightBuilder);
//设置起始页
searchSourceBuilder.from((pageNum - 1) * pageSize);
//设置页大小
searchSourceBuilder.size(pageSize);
//指定索引
Search search = new Search.Builder(searchSourceBuilder.toString())
.addIndex("book")
.build();
SearchResult result = null ;
List list = new ArrayList<>();
try {
//执行查询操作
result = jestClient.execute(search);
System.out.println("本次查询共查到:"+result.getTotal()+"个关键字!"+result.getJsonObject());
List> hits = result.getHits(EsFileInfo.class);
for (SearchResult.Hit hit : hits) {
EsFileInfo source = hit.source;
//获取高亮后的内容
Map> highlight = hit.highlight;
List file_name = highlight.get("FILE_NAME");//高亮后的title
if(file_name!=null){
source.setFile_name(file_name.get(0));
}
List cOntent= highlight.get("attachment.content");//高亮后的title
if(content!=null){
source.getEsDoc().setContent(content.get(0));
}
System.out.println("姓名:"+source.getFile_name());
System.out.println("作者:"+source.getEsDoc().getAuthor());
System.out.println("内容:"+source.getEsDoc().getContent());
list.add(source);
}
return list;
} catch (IOException e) {
e.printStackTrace();
return new ArrayList<>();
}
}
@Override
public int findPublishedCountByKeyWord(String keyWord) {
//处理特殊字符
keyWord = QueryParser.escape(keyWord);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.boolQuery()
.should(QueryBuilders.queryStringQuery(keyWord).field("FILE_NAME"))
.should(QueryBuilders.queryStringQuery(keyWord).field("attachment.content")));
//初始化高亮对象
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("FILE_NAME");//高亮title
highlightBuilder.field("attachment.content");
highlightBuilder.preTags("").postTags("");//高亮标签
//设置高亮
searchSourceBuilder.highlighter(highlightBuilder);
//设置页大小
searchSourceBuilder.size(10000);
//指定索引
Search search = new Search.Builder(searchSourceBuilder.toString())
.addIndex("book")
.build();
SearchResult result = null ;
try {
result = jestClient.execute(search);
System.out.println("本次查询共查到:"+result.getTotal()+"个关键字!"+result.getJsonObject());
List> hits = result.getHits(EsFileInfo.class);
return hits.size();
} catch (IOException e) {
e.printStackTrace();
return new ArrayList<>().size();
}
}
}


import com.google.gson.annotations.SerializedName;
import org.apache.poi.hmef.Attachment;
import java.util.Map;
/**
* es查询出的文件信息结果类
*/
public class EsFileInfo {
@SerializedName("FILE_ID")
private String file_id;
@SerializedName("FILE_NAME")
private String file_name;
@SerializedName("FILE_SAVE_NAME")
private String file_save_name;
//编译成另一个名字
@SerializedName("attachment")
private EsDoc esDoc;
public String getFile_id() {
return file_id;
}
public void setFile_id(String file_id) {
this.file_id = file_id;
}
public String getFile_name() {
return file_name;
}
public void setFile_name(String file_name) {
this.file_name = file_name;
}
public String getFile_save_name() {
return file_save_name;
}
public void setFile_save_name(String file_save_name) {
this.file_save_name = file_save_name;
}
public EsDoc getEsDoc() {
return esDoc;
}
public void setEsDoc(EsDoc esDoc) {
this.esDoc = esDoc;
}
}

package com.pridecn.file.domain;
import com.google.gson.annotations.SerializedName;
/**
* 文件实体附件类
*/
public class EsDoc {
// @SerializedName("attachment.author")
private String author;
// @SerializedName("attachment.content")
private String content;
// @SerializedName("attachment.date")
private String date;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.cOntent= content;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}

QueryBuilders的几个分词方法的区别:


    /**
     * 默认的standard analyzer分词规则:

     * 去掉大部分标点符号,并以此分割原词为多个词,把分分割后的词转为小写放入token组中。

     * 对于not-analyzed的词,直接把原词放入token组中。

     * matchQuery的机制是:先检查字段类型是否是analyzed,如果是,则先分词,再去去匹配token;如果不是,则直接去匹配token。

     * id=id2,默认分词,id2不分词。

     * 以wwIF5-vP3J4l3GJ6VN3h为例:

     * id是的token组是[wwif5,vp3j4l3gj6vn3h]

     * id2的token组是[wwIF5-vP3J4l3GJ6VN3h]

     * 可以预计以下结果:

     * 1.matchQuery("id", "字符串"),"字符串"分词后有[wwif5,vp3j4l3gj6vn3h]其中之一时,有值。

     * 如:wwIF5-vP3J4l3GJ6VN3h,wwif5-vp3j4l3gj6vn3h,wwIF5,wwif5,wwIF5-6666等等。

     * 2.matchQuery("id2", "wwIF5-vP3J4l3GJ6VN3h"),有值。

     * 特别说明:

     * 在创建索引时,如果没有指定"index":"not_analyzed"

     * 会使用默认的analyzer进行分词。当然你可以指定analyzer。

     * 在浏览器中输入:

     * http://localhost:9200/_analyze?pretty&analyzer=standard&text=J4Kz1%26L
     * bvjoQFE9gHC7H

     * 可以看到J4Kz1&LbvjoQFE9gHC7H被分成了:j4kz1和lbvjoqfe9ghc7h

///

*
     * 默认的standard analyzer分词规则:

     * 去掉大部分标点符号,并以此分割原词为多个词,把分分割后的词转为小写放入token组中。

     * 对于not-analyzed的词,直接把原词放入token组中。

     * termQuery的机制是:直接去匹配token。

     * id=id2,默认分词,id2不分词。

     * 以wwIF5-vP3J4l3GJ6VN3h为例:

     * id是的token组是[wwif5,vp3j4l3gj6vn3h]

     * id2的token组是[wwIF5-vP3J4l3GJ6VN3h]

     * 可以预计以下结果:

     * 1.termQuery("id", "wwif5"),有值。

     * 2.termQuery("id", "vp3j4l3gj6vn3h"),有值。

     * 3.termQuery("id2", "wwIF5-vP3J4l3GJ6VN3h"),有值。


总结:match query搜索的时候,首先会解析查询字符串,进行分词,然后查询,而term query,输入的查询内容是什么,就会按照什么去查询,并不会解析查询内容,对它分词。QueryBuilders.queryStringQuery(keyWord).field("FILE_NAME")与matchquery相似

 


推荐阅读
  • 前言本篇为大家总结社区多人合作常见的场景和对应的git操作命令。本篇非新手教程,阅读本篇前需具备Git基础知识。Git入门教程请参考https://www ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了Nutch相关的知识,希望对你有一定的参考价值。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 本文介绍了绕过WAF的XSS检测机制的方法,包括确定payload结构、测试和混淆。同时提出了一种构建XSS payload的方法,该payload与安全机制使用的正则表达式不匹配。通过清理用户输入、转义输出、使用文档对象模型(DOM)接收器和源、实施适当的跨域资源共享(CORS)策略和其他安全策略,可以有效阻止XSS漏洞。但是,WAF或自定义过滤器仍然被广泛使用来增加安全性。本文的方法可以绕过这种安全机制,构建与正则表达式不匹配的XSS payload。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • 设计模式——模板方法模式的应用和优缺点
    本文介绍了设计模式中的模板方法模式,包括其定义、应用、优点、缺点和使用场景。模板方法模式是一种基于继承的代码复用技术,通过将复杂流程的实现步骤封装在基本方法中,并在抽象父类中定义模板方法的执行次序,子类可以覆盖某些步骤,实现相同的算法框架的不同功能。该模式在软件开发中具有广泛的应用价值。 ... [详细]
  • 本文介绍了在sqoop1.4.*版本中,如何实现自定义分隔符的方法及步骤。通过修改sqoop生成的java文件,并重新编译,可以满足实际开发中对分隔符的需求。具体步骤包括修改java文件中的一行代码,重新编译所需的hadoop包等。详细步骤和编译方法在本文中都有详细说明。 ... [详细]
  • ES基本原理名词解释In-memorybuffer:ES内存缓冲区,新建的document写入的地方document:索引和搜索的 ... [详细]
author-avatar
mobiledu2502925077
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有