这可能是Solr比较全的知识整理

10 篇文章 0 订阅

Solr介绍

Solr是建立在Apache Lucene ™之上的流行,快速,开放源代码的企业搜索平台。Solr具有高度的可靠性,可伸缩性和容错性,可提供分布式索引,复制和负载平衡查询,自动故障转移和恢复,集中式配置等。Solr为许多世界上最大的互联网站点提供搜索和导航功能。

文档

Solr官网

Solr8.3官方文档

Solr W3Cschool官方文档

用法

SolrJ

SolrJ是一个API,它使用Java(或任何基于JVM的语言)编写的应用程序可以轻松地与Solr交谈。SolrJ隐藏了许多连接到Solr的细节,并允许您的应用程序通过简单的高级方法与Solr交互。SolrJ支持大多数Solr API,并且具有高度可配置性。不同版本的Solr都有对应的SolrJ,例如我们系统有5.5.3版本的SolrJ和8.3.0版本的SolrJ

  1. SolrClient

支持不同协议不同版本的初始化,可以使用一个core的地址,并且可以设置超时时间等信息


private final static SolrClient solr = new HttpSolrClient.Builder(ApolloConfigUtil.getSiteSolrUrl())

        .withConnectionTimeout(10000)

        .withSocketTimeout(60000)

        .build();

  1. 在SolrJ查询

SolrJ中有一个SolrQuery类,它提供了一些方便的方法,可以大大简化查询的创建。我们只需要关注构建SolrQuery即可


SolrQuery solrQuery = new SolrQuery();

solrQuery.setStart(query.getPageIndex() * query.getPageSize());

solrQuery.setRows(query.getPageSize());

solrQuery.setQuery("rentalUnitId : 3047 && projectId : 624");

solrQuery.setParam("sort", "order by lastFollowTime desc");

  1. SolrJ对象绑定

SolrJ通过将文档隐式地转换到任何已特别标注了Field注释的类与来回的类来支持此操作。


public static class ProjectSolr {

  @Field public String id;

  @Field public String name;

}

索引或者更新这个实体类的数据


final SolrClient client = getSolrClient();



final Project project = new Project();

project.setId(624);

project.setName("测试")

final UpdateResponse response = client.addBean("project", project); // addBean又能新增也能更新索引

IK分词器

具体业务:前台网站关键词搜索

在这里插入图片描述

Solr中自带了一个分词器,但是大部分都是使用IK-Analyzer来实现中文分词。因为IK更新频率比较高,并且对中文分词友好

在这里插入图片描述

关于IK,IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。

  • 采用了特有的“正向迭代最细粒度切分算法”,具有60万字/秒的高速处理能力。

  • 采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。

  1. 构建步骤参考参考IKAnalyzer使用说明

  2. 下载并解压IKAnalyzer使用上面的下载地址下载IK,并解压,将IK目录下src/main/resources中的5个文件拷贝到Solr的WEB-INF/classes/目录下

① IKAnalyzer.cfg.xml

② ext.dic

③ stopword.dic

④ ik.conf

⑤ dynamicdic.txt

  1. 配置IK中文分词器schema中加入IK分词器配置

<!-- ik分词器 -->

<fieldType name="text_ik" class="solr.TextField">

  <analyzer type="index">

      <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>

      <filter class="solr.LowerCaseFilterFactory"/>

  </analyzer>

  <analyzer type="query">

      <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" conf="ik.conf"/>

      <filter class="solr.LowerCaseFilterFactory"/>

  </analyzer>

</fieldType>

  1. 启动测试启动Solr访问页面,选择用我们自己配置的text_ik分词器:输入文本进行测试

  2. 如何使用在manage-scheme中新增一个字段的时候,将type设置为text_ik即可


<field name="keywordStr" type="text_ik" uninvertible="false" docValues="false" indexed="true" stored="true"/>

空间搜索

具体业务:

在这里插入图片描述

Solr 具有复杂的地理空间支持,包括在给定位置(或边界框内)的指定距离范围内搜索,按距离排序,甚至可以通过距离来提高结果。Solr空间搜索原理分析与实践

字段类型:SpatialRecursivePrefixTreeFieldType,不仅可以用于点的范围查询,也可以用于多边形的查询

  1. manage-schema中的配置

<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType" geo="true" maxDistErr="0.001" distErrPct="0.025" distanceUnits="kilometers"/>



<field name="stationPosition" type="location_rpt" uninvertible="true" indexed="true" stored="true"/>

  1. 使用“经度 纬度”这样的字符串格式将经纬度索引到stationPosition字段

  2. 查询使用半径搜索


SolrQuery params = new SolrQuery();   

params.set("q", "*:*");    

params.set("fq", "{!geofilt}");           //距离过滤函数

params.set("pt", "118.227985 39.410722"); //当前经纬度

params.set("sfield", "station_position"); //经纬度的字段

params.set("d", "50"); //就近 d km的所有数据

//params.set("score", "kilometers"); 

params.set("sort", "geodist() asc");  //根据距离排序:由近到远

params.set("start", "0");  //记录开始位置

params.set("rows", "100");  //查询的行数

params.set("fl", "*,_dist_:geodist(),score");//查询的结果中添加距离和score

  1. 查询使用多边形搜索

SolrQuery params = new SolrQuery();   

//q=geo:"Intersects(POLYGON((-10 30, -40 40, -10 -20, 40 20, 0 0, -10 30)))"

params.set("q", "station_position:\"Intersects(POLYGON((118 40, 118.5 40, 118.5 38, 118.3 35, 118 38,118 40)))\"");    

params.set("start", "0");  //记录开始位置

params.set("rows", "100");  //查询的行数

params.set("fl", "*");

Query

  1. 基本查询
  • q:查询的关键字,此参数最为重要,例如,q=id:1,默认为q=:

  • fl:指定返回哪些字段,用逗号或空格分隔,注意:字段区分大小写,例如,fl= id,title,sort

  • start:返回结果的第几条记录开始,一般分页用,默认0开始

  • rows:指定返回结果最多有多少条记录,默认值为 10,配合start实现分页

  • sort:排序方式,例如id desc 表示按照 “id” 降序,多个字段:score desc,price asc

  • wt:(writer type)指定输出格式,有 xml, json, php等

  • fq:(filter query)过虑查询,提供一个可选的筛选器查询。返回在q查询符合结果中同时符合的fq条件的查询结果,例如:q=id:1&fq=sort:[1 TO 5],找关键字id为1 的,并且sort是1到5之间的。

  • df:默认的查询字段,一般默认指定。

  • qt:(query type)指定那个类型来处理查询请求,一般不用指定,默认是standard。

  • indent:返回的结果是否缩进,默认关闭,用 indent=true|on 开启,一般调试json,php,phps,ruby输出才有必要用这个参数。

  1. Solr的检索运算符
  • “:”: 指定字段查指定值,如返回所有值*😗

  • “?”: 表示单个任意字符的通配

  • “*” 表示多个任意字符的通配(不能在检索的项开始使用*或者?符号)

  • “~” 表示模糊检索,如检索拼写类似于”roam”的项这样写:roam将找到形如foam和roams的单词;roam0.8,检索返回相似度在0.8以上的记录。

  • AND、|| 布尔操作符

  • OR、&& 布尔操作符

  • NOT、!、-(排除操作符不能单独与项使用构成查询)

  • “+” 存在操作符,要求符号”+”后的项必须在文档相应的域中存在²

  • ( ) 用于构成子查询

  • [] 包含范围检索,如检索某时间段记录,包含头尾,date:[201507 TO 201510]

  • {} 不包含范围检索,如检索某时间段记录,不包含头尾date:{201507 TO 201510}

  • (: -param:*):查询字段为null

Facet

将以导航为目的的查询结果成为facet,在用户查询的结果上根据分类增加了count信息,然后用户根据count信息做进一步搜索。

具体业务:
在这里插入图片描述


json.facet={marketCategories:{field:marketIds,type:terms,limit:100,facet:{uniqueCount:"unique(projectId)"}},districtCategories:{field:districtCode,type:terms,facet:{uniqueCount:"unique(projectId)"}}}

  • facet 参数字段必须被索引

  • facet=on 或 facet=true

  • facet.field 分组的字段

  • facet.prefix 表示Facet字段前缀

  • facet.limit Facet字段返回条数

  • facet.offict 开始条数,偏移量,它与facet.limit配合使用可以达到分页的效果

  • facet.mincount Facet字段最小count,默认为0

  • facet.missing 如果为on或true,那么将统计那些Facet字段值为null的记录

  • facet.sort 表示 Facet 字段值以哪种顺序返回 .格式为 true(count)|false(index,lex),true(count) 表示按照 count 值从大到小排列,false(index,lex) 表示按照字段值

  • 自然顺序 (字母 , 数字的顺序 ) 排列 . 默认情况下为 true(count)

  • Facet Functions

  • JsonFacet(<facet_name>:{<facet_type>:<facet_parameter(s)>})

Group

facet只是简单统计记录数,如果需要获取doc信息,并不能为每组数据返回实际的数据回来,查询实际数据还需要再次进行查询,group类似于关系型数据库中的group by,除了分组外,还能返回实际数据

项目具体实现参考:com.clinks.project.dl.daosolr.ProjectSolrDAO#buildGroupSolrQuery

  • group:如果为true,查询结果将被分组。

  • group.field:结果分组字段的名称。该字段必须是单值的,并且要么是索引的,要么是具有值源的字段类型,并且在函数查询中工作,例如ExternalFileField。它也必须是基于字符串的字段,如StrField或者TextField

  • group.func:根据函数查询的唯一值进行分组。

  • group.query:返回与给定查询匹配的一组文档。

  • group.limit:指定每个组返回的结果数量。默认值是1。

  • group.offset:指定每个组的文档列表的初始偏移量。

  • group.sort:指定 Solr 如何对每个组中的文档进行排序。如果group.sort未指定,则默认行为是使用与sort参数相同的有效值。

  • group.facet:确定是否为在 facet.field 参数中指定的字段分面计算分组的分面。根据第一个指定的组计算分组的分面。和正常的字段分面一样,字段不应该被标记(否则计算每个标记的计数)。分组的分面支持单个和多值字段。默认是false。

Highlight

高亮显示在搜索中使用的比较多,比较常用的有三种使用方式,如果要对某field做高亮显示,必须对该field设置

项目实现代码参考:com.clinks.project.dl.daosolr.ProjectSolrDAO#setHighlight

DelatImport FullImport

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值