Apache Solr实战:从基础查询到HBase集成的完整指南

Words 5204Read Time 14 min
2020-4-12
2026-2-11
cover
type
Post
status
Published
date
Apr 12, 2020 15:02
slug
summary
本文全面介绍Apache Solr全文搜索引擎的使用方法,涵盖Solr的核心概念、安装部署、查询操作(基本查询、统计、分组、多维统计、高亮)、数据修改删除、字段类型配置,以及与HBase集成实现实时索引的完整实践方案。适合需要构建企业级搜索系统的开发者。
tags
Solr
HBase
category
Data Engineering
icon
password
wordCount
5614

前言

在海量数据时代,如何快速检索信息成为每个开发者必须面对的挑战。想象一下,你有数百万条商品数据,用户输入"红色连衣裙",系统需要在毫秒级返回最相关的结果——这就是全文搜索引擎的价值所在。
🎯
核心要点
本文将带你全面了解Apache Solr搜索引擎:
  • 基础概念:理解Solr的工作原理和核心特性
  • 安装部署:手把手完成Solr环境搭建
  • 实战查询:掌握基本查询、统计、分组、高亮等核心功能
  • 数据管理:学会增删改操作和字段配置
  • 集成实践:将Solr与HBase结合实现实时索引

什么是Solr

Solr是基于Apache Lucene构建的搜索服务器,Apache Lucene是基于Java的开源信息检索库。它旨在驱动功能强大的文档检索应用程序-无论您需要根据用户的查询向其提供数据的任何地方,Solr都能为您服务 - Solr能为你想要搜索的数据建立索引,提高搜索效率 - Solr能配置各种分词器,如英文分词器,中文分词器。分词器能将你输入的搜索文本切分成几个词,然后搜索出最匹配这几个词的数据。例如中文分词器(不同类别的中文分词分词结果不一样),输入“我是中国人”,Solr会将这句话切分为“我”,“是”,“中国人”去进行搜索。 - Solr支持分布式搜索,将搜索数据分布在数个solr服务器上,称之为SolrCloud集群。当Solr节点接收到搜索请求时,该请求将在后台路由到碎片的副本,该碎片是要搜索的集合的一部分。

Solr安装

  1. 下载Solr安装包 可从Solr网站获得Solr。下载最新版本 有三个单独的程序包:
  • solr-8.5.0.tgz 用于Linux / Unix / OSX系统
  • solr-8.5.0.zip 用于Microsoft Windows系统
  • solr-8.5.0-src.tgz软件包Solr源代码。如果您想在Solr上进行开发而不使用官方的Git存储库,这将很有用。
  1. 解压solr bash $ cd ~/ $ tar zxf solr-8.5.0.tgz 安装Solr之后,您将在其中看到以下目录和文件:
      • bin/ 该目录包含几个重要的脚本,这些脚本将使使用Solr更加容易。
        • solr和solr.cmd 这是Solr的控制脚本,也称为bin/solr(* nix)/ bin/solr.cmd(Windows)。该脚本是启动和停止Solr的首选工具。在以SolrCloud模式运行时,您还可以创建集合或核心,配置身份验证并使用配置文件。
        • post 它提供了用于发布内容到Solr一个简单的命令行界面。
        • solr.in.sh和solr.in.cmd 这些分别是* nix和Windows系统的属性文件。在此配置Java,Jetty和Solr的系统级属性。使用bin/solr/时bin/solr.cmd,可以覆盖许多设置,但这使您可以将所有属性设置在一个位置。
        • install_solr_services.sh 该脚本在* nix系统上用于将Solr作为服务安装。在将Solr投入生产一节中对此进行了详细描述。
      • contrib/ Solr的contrib目录包括用于Solr的特殊功能的附加插件。
      • dist / 该dist目录包含主要的Solr .jar文件。
      • docs / 该docs目录包含指向Solr的在线Javadocs的链接。
      • example/ 该example目录包括几种类型的示例,这些示例演示了各种Solr功能。有关此目录中内容的更多详细信息,请参见下面的Solr示例部分。
      • licenses/ 该licenses目录包含Solr使用的第三方库的所有许可证。
      • server/ 该目录是Solr应用程序的心脏所在的位置。此目录中的自述文件提供了详细的概述,但以下是一些要点:
      • Solr’s Admin UI (server/solr-webapp)
      • Jetty libraries(server/lib)
      • 日志文件(server/logs)和日志配置(server/resources)。有关如何自定义Solr的默认日志记录的更多详细信息,请参阅配置日志记录部分。
      • 样本配置集(server/solr/configsets)
  1. 启动solr服务
    1. 如果您正在运行Windows,则可以通过运行bin.cmd来启动Solr 。
       
  1. 检测solr是否在运行
    1.  
  1. 打开浏览器 访问 http://localhost:8983/solr/
    1. notion image

Solr使用

打开sorl页面,我们可以看到如下的图所示的页面:
notion image
左侧为操作菜单,从上往下依次是: - 仪表盘(Dashboard): 在仪表盘页面能看到一些系统的基本信息,如启动时间,版本号,jvm的配置,磁盘剩余空间 - Log日志(Logging): 可以查看各级别的日志 - 云集群管理(Cloud) 集群的管理界面,看到所有的节点状态,zookeeper的状态。 - 数据源管理(Collections) 数据源的管理界面 - 配置项查看(Java Properties) 能看见java的所有配置项 - 线程转储(Thread dump) 一个诊断Java应用问题的工具,Thread dumps出来的信息包含线程;线程的运行状态、标识和调用的堆栈;调用的堆栈包含完整的类名,所执行的方法 - 建议(Suggestions): 对于集群的一些建议 - 选择数据源: 选择数据源后会出现分词,查询等操作 - 选择核心 每个核心都是solr的一个实例,这里可以查看solr的核心

查询

选择数据源后,会出现query操作选项
notion image
左侧为查询的参数,右侧为查询结果,下面将详细介绍参数的使用
notion image

基本查询

参数名
默认
类型
说明
例子
fl
N/A
string
查询的字段,多个字段用逗号隔开
查询Id,name字段:&fl=id,name
q
N/A
string
Where条件,高亮字段放这里
1.AND: &q=id:1 AND (name=2)2.OR:&q=id:1 OR name=23.查询id>1并且id<=3&q=id:(1 TO 3]4.查id in (1,2,3)&q=(id:1 OR id:2 OR id:3)
fq
N/A
string
Where条件,非高亮字段放这里
参考q
sort
N/A
string
排序字段
&sort=id desc
start
N/A
int
offset
&start=0
rows
N/A
int
limit
&rows=10
indent
False
Boolean
返回的结果是否缩进,默认关闭,用 indent=true
on 开启,一般调试json,php,phps,ruby输出才有必要用这个参数。
wt
xml
String
指定查询输出结构格式,默认为“xml”。在solrconfig.xml中定义了查询输出格式:xml、json、python、ruby、php、phps、custom。
&wt=xml&wt=json
omitHeader
False
Boolean
设置是否忽略查询结果返回头信息
&omitHeader=false&omitHeader=true
debugQuery
False
Boolean
设置返回结果是否显示Debug信息。
&debugQuery=true&debugQuery=false
timeAllowed
N/A
int
定义要处理的查询的时间。如果处理超时,只返回部分信息。单位毫秒
&timeAllowed=100

检索运算

  • “:” 指定字段查指定值,如返回所有值:
  • “?” 表示单个任意字符的通配
  • ” 表示多个任意字符的通配(不能在检索的项开始使用或者?符号)
  • “ ~ ” 表示模糊检索,如检索拼写类似于”roam”的项这样写:roam~ 将找到形如foam和roams的单词;roam~ 0.8,检索返回相似度在0.8以上的记录。
  • AND、|| 布尔操作符
  • OR、&& 布尔操作符
  • NOT、!、-(排除操作符不能单独与项使用构成查询) -“+” 存在操作符,要求符号”+”后的项必须在文档相应的域中存在²
  • ( ) 用于构成子查询
  • [] 包含范围检索,如检索某时间段记录,包含头尾,date:[201507 TO 201510]
  • {} 不包含范围检索,如检索某时间段记录,不包含头尾date:{201507 TO 201510}

统计查询

参数名
默认
类型
说明
例子
stats
False
Boolean
是否开启统计
&stats=true&stats=false
stats.field
N/A
String
需要统计的字段
&stats.field=id
stats.facet
N/A
String
返回统计的结果集 min:最小值 max:最大值 sum:总和 count: 记录数,也就是多少行记录 missing: 结果集中,有多少条记录是空值 sumOfSquares: 平方和(x1^2 + x22+xn2) mean:平均数(x1+x2+xn)/n stddev: 标准差
&stats.facet=idCount

例:按id统计

参数:
结果:
notion image

分组查询

参数名
默认
类型
说明
例子
Group
False
Boolean
开启分组查询
&group=true&group=false
group.field
N/A
String
分组字段
&group.field=id
group.func
N/A
String
指定聚合函数,avg:求平均值 AVG(DISTINCT
ALL
group.query
N/A
String
查询语句,查询分组后集合,用法和q与fq一样
&group.query=address_id:1000
group.limit
1
Int
每组返回多数条结果,默认1
&group.limit=200
group.offset
0
Int
指定每组结果开始位置/偏移量
&group.offset=10
group.sort
N/A
String
分组结果排序字段
&group.sort=id
group.format
grouped
String
两值grouped与simple.设置为simple可以使得结果以单一列表形式返回
&group.format=simple&group.format=grouped
group.main
Fals
Boolean
group.main=true返回每个分组的第一条记录信息(没有分组的详细信息)
&group.main=true&group.main=false
group.ngroups
False
Boolean
设为true时,Solr将返回分组数量,默认fasle
&group.ngroups=false&group.ngroups=true
group.truncate
False
Boolean
设为true时,facet数量将基于group分组中匹相关性高的文档,默认fasle
&group.truncate=true&group.truncate=false
group.cache.percent
0
int
取值0-100,设为大于0时,表示缓存结果,默认为0。该项对于布尔查询,通配符查询,模糊查询有改善,却会减慢普通词查询。
&group.cache.percent=0&group.cache.percent=100

例:按id分组

参数:
结果:
notion image

多维统计

参数名
默认
类型
说明
例子
facet
False
Boolean
开启facet,相当于group by后再count(*)的集合
&facet=true,facet=false
facet.field
N/A
String
各自分组的字段并返回count(*)
&facet.field=id,name
facet.prefix
N/A
String
表示Facet字段值的前缀
对cpu字段进行Facet查询,返回的cpu都是以”Intel”开头的,”AMD”开头的cpu型号将不会被统计在内: &facet.field=cpu&facet.prefix=Intel
facet.sort
N/A
Boolean
表示Facet字段值以哪种顺序返回.
可接受的值为true(count)
facet.limit
100
int
限制Facet字段返回的结果条数,默认值为100.如果此值为负数,表示不限制
&facet.limit=10
facet.offset
0
int
返回结果集的偏移量,默认为0
&facet.offset=0
facet.mincount
0
int
限制了Facet字段值的最小count
&facet.mincount=10
facet.missing
N/A
Boolean
统计字段值为Null数量
&facet.missing=on, &facet.missing=true
facet.method
fc
String
enum适用于字段值比较少的情况,比如字段类型为布尔型,或者字段表示中国的所有省份.Solr会遍历该字段的所有取值,并从filterCache里为每个值分配一个filter(这里要求solrconfig.xml里对filterCache的设置足够大).然后计算每个filter与主查询的交集.fc(表示Field Cache)适用于字段取值比较多,但在每个文档里出现次数比较少的情况.Solr会遍历所有的文档,在每个文档内搜索Cache内的值,如果找到就将Cache内该值的count加1.
&facet.method=enum.&facet.method=fc
facet.enum.cache.minDf
0
int
当facet.method=enum时,此参数其作用,minDf表示minimum document frequency.也就是文档内出现某个关键字的最少次数.该参数默认值为0.设置该参数可以减少filterCache的内存消耗,但会增加总的查询时间(计算交集的时间增加了).如果设置该值的话,官方文档建议优先尝试25-50内的值.
&facet.enum.cache.minDf=30
facet.date
N/A
String
该参数表示需要进行Date Facet的字段名,与facet.field一样,该参数可以被设置多次,表示对多个字段进行Date Facet.
&facet.date=birthday
N/A
Date
与facet.date一起使用,起始时间,时间的一般格式为1995-12-31T23:59:59Z,另外可以使用”NOW”,”YEAR”,”MONTH”等等 &facet.date.start=2014-01-00T09:15:00Z
N/A
Date
与facet.date一起使用,起始时间,时间的一般格式为1995-12-31T23:59:59Z,另外可以使用”NOW”,”YEAR”,”MONTH”等等 &facet.date.end=2014-01-00T09:15:00Z
N/A
String
时间间隔,如果start为2009-1-1,end为2010-1-1.gap设置为”+1MONTH”表示间隔1个月,那么将会把这段时间划分为12个间隔段.注意”+”因为是特殊字符所以应该用”%2B”代替. &facet.date.gap=%2B1MONTH
facet.date.other
N/A
String
取值范围为before
after
facet.date.hardend
N/A
Boolean
取值可以为true
false,默认为false.它表示gap迭代到end处采用何种处理.举例说明start为2009-1-1,end为2009-12-25,gap为”+1MONTH”,hardend为false的话最后一个时间段为2009-12-1至2010-1-1;hardend为true的话最后一个时间段为2009-12-1至2009-12-25.
facet.pivot
N/A
String
多维统计
统计各个电影类别的各导演的电影数:&facet.pivot=category,author

例子1

查询 2014-01到2014-12的birthday,按每月分区 参数
结果

例子2

按电影类别分类,再统计类别基础上各导演的电影数 参数:
结果:
notion image

高亮

参数名
默认
类型
说明
例子
hl
false
Boolean
是否开启高亮
&hl=true&hl=false
hl.fl
N/A
String
设定高亮显示的字段,用空格或逗号隔开的字段列表。要启用某个字段的highlight功能,就得保证该字段在schema中是stored。如果该参数未被给出,那么就会高亮默认字段 standard handler会用df参数,dismax字段用qf参数。你可以使用星号去方便的高亮所有字段。如果你使用了通配符,那么要考虑启用hl.requiredFieldMatch选
&hl.fl=id
hl.requireFieldMatch
False
Boolean
如果置为true,除非用hl.fl指定了该字段,查询结果才会被高亮
&hl.requireFieldMatch=ture&hl.requireFieldMatch=false
hl.usePhraseHighlighter
False
Boolean
如果一个查询中含有短语(引号框起来的)那么会保证一定要完全匹配短语的才会被高亮
&hl.usePhraseHighlighter=true&hl.usePhraseHighlighter=false
hl.highlightMultiTerm
False
Boolean
如果使用通配符和模糊搜索,那么会确保与通配符匹配的term会高亮。默认为false,同时hl.usePhraseHighlighter要为true
&hl.highlightMultiTerm=true&hl.highlightMultiTerm==false
hl.fragsize
100
Int
返回的最大字符数。默认是100.如果为0,那么该字段不会被fragmented且整个字段的值会被返回
&hl.fragsize=0&hl.fragsize=100

修改与删除

可以通过api或者web界面操作: - api Api:http://hdp-e-1.data.dc.zjft.com:8886/solr/ranger_audits/update Method:post Request-Handler (qt): 只能是/update Document Type:文档类型 Document:文档 Overwrite: 为true,说明如果id重复则覆盖以前的值;为false说明如果id重复不覆盖以前的
  • 界面操作 选择数据源后,会出现documents操作选项
    • notion image
      notion image

修改(新增)文档

notion image

删除文档

notion image
Document:
commit不能少,表示提交

配置solr字段类型

solr在摄取数据前应该配置好字段类型,修改后仅对新数据生效,旧数据不会生效,再创建集合后就应该马上配置好
  1. 选colletion的schema
    1. notion image
  1. 点击AddFile
  • AddFile:添加字段
  • Add Dynamic Filed:添加通配字段,即可以使用通配符来指定字段(如 patient_* 那么以patient_开头的字段都会使用这个配置)
  • Add copy filed :添加重复数据字段
  1. 以通配字段为例,以map_patient_case.开头的字段,都匹配成string类型,并且可以排序与索引
    1. notion image

集成HBase

solr配合Hbase-indexer,通过xml文件指定需要索引的表与字段,当数据进入hbase的相应的表后,数据就会被索引到Solr搜索引擎。建立Hbase与Solr索引之前需要设计好字段的类型并且在Solr上配置好
 
notion image

安装Hbase-indexer

HBase Indexer项目为存储在HBase中的内容提供索引(通过Solr)。它提供了一种定义索引规则的灵活且可扩展的方式,并且可以按比例缩放。索引是异步执行的,因此不会影响HBase上的写吞吐量。SolrCloud用于存储实际索引,以确保索引的可伸缩性。
  1. 获取HBase索引器 签出代码并构建tar.gz发行版
    1.  
  1. 接下来,解压缩tar.gz发行版(在下面的示例中,将其解压缩到$ HOME目录下)
    1.  
  1. 配置HBase索引器 在hbase-indexer目录中,编辑文件conf/hbase-indexer-site.xml并配置ZooKeeper连接字符串(两次,一次用于hbase-indexer,一次用于hbase,或者您也可以将其复制hbase-site.xml到conf目录)
    1. 如果尚未全局定义JAVA_HOME,并且bin / hbase-indexer脚本会抱怨找不到Java,则可以在脚本中设置JAVA_HOME conf/hbase-indexer-env.sh
  1. 配置HBase 为了使用HBase索引器,必须在HBase中启用复制。还可以设置许多其他HBase设置来优化HBase索引器的工作。
    1. 将以下设置添加到所有HBase区域服务器上的hbase-site.xml配置中,然后重新启动HBase
  1. 将索引器jar添加到HBase HBase索引器包含两个必须在HBase的类路径中的jar文件。将它们从解压缩的hbase-indexer安装的lib目录复制到每个区域服务器的HBase的lib目录中。
    1. 测试habse-indexer 进入habase-indexer目录,进入bin目录
      1. 上面命令将输出目前索引集合

    solr索引Hbase数据

    1. habse需要打开备份 进入hbase命令模式后,输入下面代码,table换成需要索引的表名
      1.  
    1. solr instance设置auto commit(已经设置,无需重复设置)
      1. 修改成下面内容
        改了配置后重启solrinstance, 然后需要删除collection,重新创建才有效!!!
    1. solr创建集合 下面语句创建了一个collertion1的集合
      1. sudo -u infra-solr /usr/lib/ambari-infra-solr/bin/solr create_collection -c collection1 -shards 1 -replicationFactor 1
    1. 启动habse-index(已经启动可跳过) 进入hbase-indexer目录
      1. bash nohup bin/hbase-indexer server >>/var/log/hbase-indexer.log 2>&1 &
         
    1. 编写indexer的schema
        • name为solr字段名
        • value为hbase字段名,支持通配符
        • type为字段类型 非宽表例子hkpmi_patient_data.xml
          • xml <?xml version="1.0"?> <indexer table="hkpmi_all_wide"> <field name="patient_id" value="f1:patient_data.patient_id" type="string"/> <field name="process_dtm" value="f1:patient_data.process_dtm" type="string"/> <field name="patient_name" value="f1:patient_data.patient_name" type="string"/> </indexer>
            宽表例子hkpmi_patient_nok_wide.xml
            xml <?xml version="1.0"?> <indexer table="hkpmi_all_wide" mapping-type="column" unique-key-formatter="com.ngdata.hbaseindexer.uniquekey.StringUniqueKeyFormatter"> <field name="patient_id" value="f1:patient_nok.patient_id" type="string"/> <field name="p1" value="f1:patient_nok.p1_*" type="string"/> <field name="p2" value="f1:patient_nok.p2_*" type="string"/> <field name="process_dtm" value="f1:patient_nok.process_dtm_*" type="string"/> </indexer>
         
        一个hbase table可以建多个indexer,每个indexer就是合并前的表 indexer的id需要指定为该表的主键,如果没有主键,需要造一个出来,否则无法更新或删除。
    1. 添加索引 根据schema创建indexer
      1. $ZK_HOST 为zookeeper集群的ip $ROOT_DIR为habase目录路径 运行下面脚本创建一个宽表与一个非宽表
        参数解析:
        • n:索引名
        • c:schema文件路径
        • cp:额外参数,后面带参数名与参数值
        • solr.zk:zookeeper集群ip地址,逗号分隔
        • solr.collection:指定同步到哪个solr集合
    1. 删除索引 $ROOT_DIR为habse-indexer目录

      写在最后

      Solr作为成熟的企业级搜索解决方案,在电商、内容平台、日志分析等场景中扮演着关键角色。通过本文的学习,你已经掌握了从安装到实战的完整技能链。
      未来展望:随着数据规模持续增长,Solr的分布式架构SolrCloud将成为必然选择。结合机器学习的智能排序、向量搜索等新特性,也让Solr在AI时代依然保持强大竞争力。建议在实际项目中:
      • 根据业务特点选择合适的分词器
      • 合理设计字段类型和索引策略
      • 利用facet和统计功能实现多维分析
      • 在生产环境中监控查询性能并持续优化
      搜索的艺术在于平衡精准度与性能,而Solr给了我们足够的工具来实现这种平衡。

      参考资料

      Loading...