3

Solr 对文本索引及其查询

 2 years ago
source link: https://miopas.github.io//2019/02/25/solr-02/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Solr 对文本索引及其查询 — Miopas

关于 Solr 如何对文本数据做索引(indexing)。

Solr 在建立索引和处理查询的过程中,都对文本数据进行了预处理。这个过程涉及了 Solr 的三个组件:Analyzer, Tokenizer 以及 Filter。

Analyzer

Analyzer 负责检查文本字段以及把文本转换成 token 流,在建立索引和处理查询的过程中都会被调用。一个 Analyzer 可以是一个单独的类,例如:

<fieldType name="nametext" class="solr.TextField">   
  <analyzer class="org.apache.lucene.analysis.core.WhitespaceAnalyzer"/>
</fieldType>

也可以是几个的 Tokenizer 类和 Filter 类的组合:

<fieldType name="nametext" class="solr.TextField">
  <analyzer>
    <tokenizer class="solr.StandardTokenizerFactory"/>     
    <filter class="solr.LowerCaseFilterFactory"/>     
    <filter class="solr.StopFilterFactory"/>    
    <filter class="solr.EnglishPorterFilterFactory"/>  
  </analyzer>
</fieldType>

Tokenizer

Tokenizer 负责把文本切分成 token,也就是通常所说的“分词”。分词的粒度可以是字级别,也可以是词级别,这个通过在配置文件中配置不同的 Tokenizer 类来控制。Solr 内置了多种 Tokenizer 类,在官方文档有详细的介绍。

Filter

Filter 负责检查 token 流,根据需要对 token 流进行插入、替换、删除操作,从而产生一个新的 token 流。例如删除停用词、大小写转换、单词原型化等,都是由 Filter 来处理。

更多细节参见官方文档

索引字段查询

《Solr 快速入门手册》第 2.3 节 中提到我们可以在导入数据的时候指定索引的字段(field)。

在定义字段的时候,指定后缀 _t,即可对指定字段根据** token **建立索引。Solr 内置了语种检测的功能。在默认情况下,Solr 对英文文本按空格切分为 token,对中文文本按字切分为 token。

举个例子。

运行下面的命令插入一条数据:

$ curl http://localhost:8983/solr/demo/update -d '
[
 {"id" : "book1",
  "title_t" : "The Way of Kings",
  "author_s" : "Brandon Sanderson"
 }
]'

其中 title_t 是建了索引的列。

运行查询语句:

$ curl http://localhost:8983/solr/demo/query?q=title_t:Kings

返回结果为:

{
  "responseHeader":{
    "status":0,
    "QTime":3,
    "params":{
      "q":"title_t:Kings"}},
  "response":{"numFound":1,"start":0,"docs":[
      {
        "id":"book1",
        "title_t":"The Way of Kings",
        "author_s":"Brandon Sanderson",
        "_version_":1601959657026355200}]
  }}

说明,用 Kings 作为关键词,检索成功。

运行查询语句:

$ curl http://localhost:8983/solr/demo/query?q=title_t:King

返回结果为:

{
  "responseHeader":{
    "status":0,
    "QTime":1,
    "params":{
      "q":"title_t:King"}},
  "response":{"numFound":0,"start":0,"docs":[]
  }}

因为 King 在 token 的维度上无法匹配 Kings,所以用 King 作为关键词检索失败。

这一点在 Solr Tutorial 中提到:

Indexed for full-text search so individual words or phrases may be matched.

同时,Solr 默认支持 token 级别的模糊查询,例如这个查询(在命令行运行时,需要把空格转换成 %20):

$ curl "http://localhost:8983/solr/demo2/query?q=title_t:"The%20Kings""

返回结果为:

{
  "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
      "q":"title_t:The Kings"}},
  "response":{"numFound":1,"start":0,"docs":[
      {
        "id":"book1",
        "title_t":"The Way of Kings",
        "author_s":"Brandon Sanderson",
        "_version_":1626406079247155200}]
  }}

The Kings 作为关键词来查询,发现尽管 The Way of Kings 不包含 The Kings 字符串,但由于包含 TheKings 的 token,仍然发生了匹配。

而把 The 改成 Th 之后,则下面这个查询语句无法匹配:

$ curl "http://localhost:8983/solr/demo2/query?q=title_t:"Th%20Kings""

返回结果为:

{
  "responseHeader":{
    "status":0,
    "QTime":1,
    "params":{
      "q":"title_t:Th Kings"}},
  "response":{"numFound":0,"start":0,"docs":[]
  }}

另外,如果 _t 后缀的 field 的内容是 json 格式的字符串,会把 json object 中的 key 和 value 的字符串作为 token 来建立索引。

查询语句的引号

某次踩坑的时候发现,Solr 查询语句中的引号有不同处理。在上面那个例子中,虽然我们在查询语句中写的是 q=title_t:"The%20Kings",但实际发生的查询中 The Kings 是没有带引号的,在查询结果中的 "params":{"q":"title_t:The Kings"} 可以看出。

如果加上引号会怎么样呢?测试如下:

$  curl "http://localhost:8983/solr/demo2/query?q=title_t:\"The%20Kings\"" 
{
  "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
      "q":"title_t:\"The Kings\""}},
  "response":{"numFound":0,"start":0,"docs":[]
  }}

从结果中的 可以看到我们给 The Kings 加上了引号,然后没有匹配到结果。这是因为加上引号之后 The Kings 会作为一个整体来匹配。相关内容在官方文档的 Specifying Terms for the Standard Query Parser 中提到:

A query to the standard query parser is broken up into terms and operators. There are two types of terms: single terms and phrases.

A single term is a single word such as "test" or "hello"

A phrase is a group of words surrounded by double quotes such as "hello dolly"

Multiple terms can be combined together with Boolean operators to form more complex queries (as described below).

Solr 的分析器,分词器和分词过滤器

Solr理解Analyzers, Tokenizers, and Filters


Recommend

  • 44

  • 37
    • 掘金 juejin.im 5 years ago
    • Cache

    MySQL索引与查询优化

    目录 About MySQL Why MySQL MySQL Index Why Index 索引是如何工作的 如何使用 创建索引 查看索引 删除索引 索引的使用原则 写操作比较频繁的列慎重加索引 索引越多占用磁盘空间越大 不要为输出列加索引

  • 26
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    为什么用了索引,查询还是慢?

    点击上方 "IT牧场" ,选择 "设为星标" 技术干货每日送达! 来源:rrd.me/f9jAG 经常有同学...

  • 12
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    OMG:为什么用了索引,查询还是慢?

    来源:rrd.me/f9jAG 经常有同学问我,我的一个SQL语句使用了索引,为什么还是会进入到慢查询之中呢?今天我们就从这个问题开始来聊一聊索引和慢查询...

  • 36

    作者介绍 李猛(ynuosoft), Elastic-stack产品深度用户,ES认证工程师,2012年接触Elasticsearch,对...

  • 7

    本文由 dbaplus 社群授权转载。 序言 Elasticsearch,中文名直译弹性搜索,不仅仅在单索引内部分片层面弹性搜索,更强的是在跨索引外围支持分片弹性搜索,同比其它分布式数据产品,此特性更鲜明,代表了 Elastic 集...

  • 9

    一文读懂MySQL的索引结构及查询优化 - 程序员八阿哥的个人空间 - OSCHINA - 中文开源技术交流社区 同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) MySQL官方文档中(

  • 3

    1、代码模块因为solrj没有提供MySQL的索引支持,所以只能基于http请求实现索引MySQL import java.io.IOException;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.Date;i...

  • 7
    • wakzz.cn 2 years ago
    • Cache

    solr(3)索引mysql数据

    1、修改配置将数据库驱动jar和solr/dist路径下的solr-dataimporthandler-x.x.x.jar复制到solr-x.x.x/server/solr-webapp/webapp/WEB-INF/lib下在solr/server/solr/核心/conf路径下添加文件data-config.xml,并添加以下内容(示范如下)

  • 1

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK