Solr
一款易于使用、对开发友好以及高性能的搜索应用程序(区别于
Lucene
,Lucene是一个java类库,提供了索引、搜索、高亮分词等功能)
初识
- 下载
- 主要目录结构
tree -L 3 -I "*.txt|*.sha1|*.jar|*.mod|example" solr-6.6.2
solr-6.6.2
├── bin
│ ├── init.d
│ │ └── solr
│ ├── install_solr_service.sh
│ ├── oom_solr.sh
│ ├── post
│ ├── solr
│ └── solr.in.sh
├── contrib
├── dist
│ ├── solrj-lib
│ └── test-framework
├── docs
│ ├── images
│ └── index.html
├── example
├── licenses
└── server
├── contexts
│ └── solr-jetty-context.xml
├── etc
│ ├── jetty-https.xml
│ ├── jetty-http.xml
│ ├── jetty-ssl.xml
│ ├── jetty.xml
│ └── webdefault.xml
├── lib
│ └── ext
├── logs
├── modules
├── resources
│ ├── jetty-logging.properties
│ └── log4j.properties
├── scripts
│ └── cloud-scripts
├── solr
│ ├── configsets
│ ├── solr.xml
│ └── zoo.cfg
└── solr-webapp
└── webapp
安装
required java 7 +
tar zxf solr-x.y.z.tgz
启停
- 启动
bin/solr start -p 8984 -c -z hd-28:2181
- 停止
bin/solr stop -p 8984
- 启动
基本概念
- Core
- Collection
- Document
- Field
Solr Cloud
SolrCloud is flexible distributed search and indexing, Solr uses ZooKeeper to manage these locations, depending on configuration files and schemas. Queries and updates can be sent to any server. 参考
解决的问题
- 替代手动索引分片
- 支持分布式索引与查询
- 负载均衡和集群容错(No Master,No Slaves; Elect Leader; first-come-first-served)
Logical
- 一个集群可以有多个集合用来存储文档
- 一个collection可以被分成数片(shard)用来存储文档
- 分片数量取决于:collection的理论数量以及单个请求的期望的并行数量
- Physical
- 一个集群由一至多个运行solr进程的节点组成
- 每个节点都包含多个
Core
- 每个
Core
都是Collection
逻辑shard
的物理Replica
- 每个
Replica
使用与collection
相同的配置 - 每个分片的复制数量取决于:集群容错与高并发下的理论值
design Schema
FieldType
,内置很多,也可以自定义,比如自定义查询或者索引时的分词器Field
<field name="price" type="float" default="0.0" indexed="true" stored="true"/>
- name 字段名称
- type FieldType的name
- default 默认值
- indexed 是否索引
- stored 字段值是否存储
- required 是否必填
- large 大字段,lazy加载
- multiValued 是否包含多个值
- docValues 列为导向(面向列)结构 参考
solr标准索引结构是倒排表(大致通过词去关联文档),采用这种方式在搜索的时候非常迅速,但是对于其他聚合功能(比如经常使用的排序、分组和高亮)是比较低效率的,比如进行分组时会将文档ID找到放置于结果集中进行排序和分组,这样的方式在solr中是极其耗费内存的,并且加载的非常慢(尤其是在数据量较多的时候)。在solr4.0之后引入了一个新的功能
DocValue
,它是在索引的时候以文档-值的结构存储(列为导向),这种方式保证了在进行分组、排序等过程中耗费内存较少并且效率较高。
Copying Fields
存储一份数据,不同的分析功能(FieldType)<copyField source="here" dest="there"/> <copyField source="here" dest="elsewhere"/>
Dynamic Fields
动态字段允许不用明确的定义Field
的名称,扩充字段时减小程序的改动
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
Other Schema Elements
其他元素- Unique Key
<uniqueKey>id</uniqueKey>
指定唯一字段,类似数据库表的主键,默认copyFields
不能用于uniqueKey
,uniqueKey
指定字段不能被分词,可以使用UUIDUpdateProcessorFactory
自动产生唯一主键
- Unique Key
Default Search Field & Query Operator
默认搜索字段与查询运算符
<defaultSearchField/> 类似于指定df查询参数 <solrQueryParser defaultOperator="OR"/> 类似于指定q.op查询参数
Schema API
参考
Collections Manager
solr提供了基于Http的管理接口,涵盖了集合的增删改查、备份、恢复、合并以及别名、角色管理等
CREATE
- api
/admin/collections?action=CREATE&name=name&numShards=number&replicationFactor=number&maxShardsPerNode=number&createNodeSet=nodelist&collection.configName=configname
- input param
参数名称 是否必填 默认值 说明 name yes
|collection name router.name no compositeId implicit 不会自动路由文档到不同的分片,查询或索引的时候需要手动指定; compositeId通过文档唯一ID进行自动分发 numShards no empty 当使用 router.name=compositeId
必填,每个collection的分片数量replicationFactor no 1
每个分片的复制数量 maxShardsPerNode no 1
每个节点上当前集合的分片数量,相同分片永远不会位于同一节点上 createNodeSet no |定义分片或复制所在节点,如 localhost:8983_solr, localhost:8984_solr,
collection.configName no |配置名称,如果没有设置则使用与collection相同名称的配置 async no |异步请求 async=<request.id>
,可通过/admin/collections?action=REQUESTSTATUS&requestid=request-id
查看结果MODIFYCOLLECTION
- api
/admin/collections?action=MODIFYCOLLECTION&collection=<collection-name>&<attribute-name>=<attribute-value>&<another-attribute-name>=<another-value>
- input param
参数名称 默认值 说明 collection name,必填 被修改的name \ 必填 maxShardsPerNode,replicationFactor,autoAddReplicas,collection.configName,rule,snitch RELOAD
当配置修改了之后,可以进行reload
- api
/admin/collections?action=RELOAD&name=name
- input param
参数名称 默认值 说明 name 必填 collection的name async 否 异步id CREATEALIAS
对一个或多个Collection创建别名,如果当前别名存在,则会替换
- api
/admin/collections?action=CREATEALIAS&name=name&collections=collectionlist
- input param
参数名称 默认值 说明 name 必填 alias name collections 必填 当前集群已存在的collection async 否 异步id DELETEALIAS
- api
/admin/collections?action=DELETEALIAS&name=name
- input param
参数名称 默认值 说明 name 必填 alias name async 否 异步id LISTALIASES
- api
/admin/collections?action=LISTALIASES
DELETE
- api
/admin/collections?action=DELETE&name=collection
- input param
参数名称 默认值 说明 name 必填 collection name async 否 异步id
Indexing
Solr可以对XML、CSV、数据库表、统一格式的文件(PDF,doc)进行索引。以下是使用最多的索引数据的三种方式:
- 使用
Apache Tika
对Office、World、PDF或者其他专有格式进行索引 - 通过HTTP上传XML文件进行索引
- 通过Solr Client API 进行操作,如果内嵌solr于应用程序中,此方式为官方推荐.
XMl
对XML数据进行索引与更新时,需要使用
Content-type: application/xml
或者Content-type: text/xml
,文档例子:<add> //<delete>> <doc> <field name="authors">Patrick Eagar</field> </doc> <doc> //.... </doc> </add>
Uploading Data with Solr Cell using Apache Tika
Solr使用
Apache Tika
来处理比较流行文件,如Word
PDF
HTML
ect.关键点
- Tika会自动识别文档类型(WORD、PDF、HTML)并适当的抽取内容,当然也可以指定
stream.type
- Tika通过SAX产生一个XHTML流来进行工作,SAX
- Solr响应Tika的SAX事件进行创建索引
- Tika 产生元数据如标题、主题、作者等,Tika formats
- Tika将抽取到的文本都放置于
content
字段 - 可以将Tika的metadata字段映射为Solr的字段
- 可以传递一些值去覆盖Tika从任何地方抽取到的值
- 可以使用XPath表达式限制Tika解析的内容
DIH
可以将关系型数据库中的结构化数据进行导入并索引,他也能对基于Http的数据源、邮件以及结构化xml索引
DIH概念以及术语
- Datasource 数据源的位置,如果是数据库则为DSN,如果为Http数据源则为URL
- Entity,是一个文档集合,包含了多个字段,对于RDBMS而言,Entity就是一个表或者视图
- Processor, 用于抽取、转换以及索引数据源中的内容,可自定义实体处理器
- Transformer,对实体集中每个字段进行转换,它可以修改字段、生成新字段、或者将多行文档转换成一行
使用步骤
- Configuring the DIH Configuration File
db-data-config.xml<dataConfig> <dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:./example-DIH/hsqldb/ex" user="sa" password="secret"/> <document> <entity name="item" query="select * from item" deltaQuery="select id from item where last_modified > '${dataimporter.last_index_time}'"> <field column="NAME" name="name" /> <entity name="feature" query="select DESCRIPTION from FEATURE where ITEM_ID='${item.ID}'" deltaQuery="select ITEM_ID from FEATURE where last_modified > '${dataimporter.last_index_time}'" parentDeltaQuery="select ID from item where ID=${feature.ITEM_ID}"> <field name="features" column="DESCRIPTION" /> </entity> <entity name="item_category" query="select CATEGORY_ID from item_category where ITEM_ID='${item.ID}'" deltaQuery="select ITEM_ID, CATEGORY_ID from item_category where last_modified > '${dataimporter.last_index_time}'" parentDeltaQuery="select ID from item where ID=${item_category.ITEM_ID}"> <entity name="category" query="select DESCRIPTION from category where ID = '${item_category.CATEGORY_ID}'" deltaQuery="select ID from category where last_modified > '${dataimporter.last_index_time}'" parentDeltaQuery="select ITEM_ID, CATEGORY_ID from item_category where CATEGORY_ID=${category.ID}"> <field column="description" name="cat" /> </entity> </entity> </entity> </document> </dataConfig>
- Configuring solrconfig.xml for DIH
solrconfig.xml
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"> <lst name="defaults"> <str name="config">/path/to/my/DIHconfigfile.xml</str> </lst> </requestHandler>
- DIH Request Parameters DIH
<dataSource driver="org.hsqldb.jdbcDriver" url="${dataimporter.request.jdbcurl}" user="${dataimporter.request.jdbcuser}" password="${dataimporter.request.jdbcpassword}" /> http://localhost:8983/solr/dih/dataimport?command=full-import&jdbcurl=jdbc:hsqldb:./example-DIH/hsqldb/ex&jdbcuser=sa&jdbcpassword=secret
Query
Query Syntax and Parsing
Common Query Parameters.
- 常用参数
参数 描述 defType 指定查询解析器 sort 对查询响应进行升序或者降序,基于响应的评分或者自他字段 start 指定偏移量开始展示内容,默认为0 rows 一次响应最多返回多少数据 fq 对搜索结果进行过滤查询 fl 限制响应返回的字段列表,如果要返回值则字段的stored=”true” or docValues=”true” timeAllowed 定义查询响应时间,如果超时,允许返回部分信息 omitHeader 如果设置为true则将header排除,如果包含的花费时间等 wt 指定返回响应的格式 The Standard Query Parser
标准分词器也被称为Lucene分词器,优点是支持健壮的、直观的语法,允许创建各种结构化查询,缺点就是不能容忍错误语法
参数 描述 q 定义查询语法,强制性必须有,如无则用*代替 q.op 指定查询表达式的默认运算符, AND
OR
df 指定查询的默认字段 sow 默认为true,用空格分词 术语
- Wildcard Searches(通配符查询):
?
代替一个字,*
代替多个 - Fuzzy Searches(模糊匹配查询):
roam~1
匹配roams
而不能foam
- Proximity Searches(距离查询、临近搜索):
"jakarta apache"~10
查询距离10个词以内的文档 - Range Searches(范围查询),
field:[52 TO 200]
field:{52 TO 200}
前者包含,后者不包含
- Wildcard Searches(通配符查询):
其他
- 指定查询字段
title:"The Right Way" AND text:go
- 布尔运算符
AND(&&)
NOT(!)
OR(||)
+
-
- 子查询
(jakarta OR apache) AND website
- 注释
"jakarta apache" /* this is a comment in the middle of a normal query string */ OR jakarta
- 指定查询字段
The DisMax Query Parser
用于处理简单的短语(不包含任何的语法)
Function Queries
可以在数字字段上使用函数查询,如
sum(a+b), div(a,b)
,DocsOther ….
Highlighting
http://localhost:8983/solr/gettingstarted/select?hl=on&q=apple&wt=json&hl.fl=manu&fl=id,name,manu,cat { "responseHeader": { "..." } }, "response": { "numFound": 1, "start": 0, "docs": [{ "id": "MA147LL/A", "name": "Apple 60 GB iPod with Video Playback Black", "manu": "Apple Computer Inc.", "cat": [ "electronics", "music" ] }] }, "highlighting": { "MA147LL/A": { "manu": [ "<em>Apple</em> Computer Inc." ] } } }
Pagination
- Basic Pagination 通过
start rows
缺点:Performance Problems with “Deep Paging”
- Cursors,
cursorMark nextCursorMark rows
Faceting
基于索引项将搜索结果封装到类目中,通过搜索词很容易的获取每个子项有多少数据量
常用参数
facet=true
启用facet查询facet.query
任意的查询语句facet.field
facet字段facet.prefix
指定前缀,不可对数字类型字段使用
http://hd-25:8983/solr/hollyvoc-36/select?facet.field=custLevel&facet.prefix=1&facet.query=txtContent:%E4%BD%A0%E5%A5%BD&facet=on&indent=on&q=*:*&wt=json
Grouping
http://localhost:8983/solr/techproducts/select?wt=json&indent=true&fl=id,name&q=solr+memory&group=true&group.field=manu_exact&rows=0 { "..." "grouped":{ "manu_exact":{ "matches":6, "groups":[{ "groupValue":"Apache Software Foundation", "doclist":{"numFound":1,"start":0,"docs":[]}, { "groupValue":"Corsair Microsystems Inc.", "doclist":{"numFound":2,"start":0,"docs":[]}, { "groupValue":"A-DATA Technology Inc.", "doclist":{"numFound":1,"start":0,"docs":[] }}, { "groupValue":"Canon Inc.", "doclist":{"numFound":1,"start":0,"docs":[] }}, { "groupValue":"ASUS Computer Inc.", "doclist":{"numFound":1,"start":0,"docs":[] } }]}}}
Client Api
说明 基于官方6.6.0的用户手册,里边大多是针对主要的内容进行翻译,在某些地方包含一些自己的理解。