solr快速上手:managed-schema标签详解(三)

0. 引言

core核心是solr中的重中之重,类似数据库中的表,在搜索引擎中也叫做索引,在solr中索引的建立,要先创建基础的数据结构,即schema的相关配置,今天继续来学习solr的核心知识:

solr快速上手:solr简介及安装(一)

solr快速上手:核心概念及solr-admin界面介绍(二)

1. schema标签

schema实际上就是solr核心的数据结构,即字段的定义集。

在solr安装目录下,有这样一个文件夹server/solr/configsets/_default/conf,里面附带了要创建索引的默认的基础配置文件。我们可以通过复制这个文件夹下的配置文件,来帮助我们快速创建索引

这些文件中有两个核心的配置文件需要我们掌握:

  • menaged-schema: 字段配置文件
  • solrconfig.xml:solr核心配置文件
    在这里插入图片描述

但在我们真正开始创建之前,还是要先学习其中schema的常用标签

首先我们需要知道,我们字段结构的定义都是在managed-schema文件中的,当然有时我们能看到又使用的是schema.xml文件,这是因为solr提供了两种定义模式,默认使用managed-schema,如果需要使用schema.xml,则需要在solrconfig.xml中配置如下标签

<schemaFactory class="ClassicIndexSchemaFactory"/>

通过上述文件夹中复制下来的managed-schema已经有各类标签的使用案例了,只不过都是注释的,我们来详细看看几个常用的标签:

<schema name="example" version="1.5">
   
    <field name="id" type="int" indexed="true" stored="true" multiValued="false" required="true"/>
    ...

	<dynamicField name="*_i"  type="pint"    indexed="true"  stored="true"/>
    ...

    <uniqueKey>id</uniqueKey>
	
	<copyField source="sourceFieldName" dest="destinationFieldName"/>

    <fieldtype name="textSimple" class="solr.TextField">
        <analyzer>
            <tokenizer class="org.lionsoul.jcseg.solr.JcsegTokenizerFactory" mode="detect"/>
        </analyzer>
    </fieldtype>
    <fieldType name="string" class="solr.StrField" sortMissingLast="true"/>
    ...
</schema>

1.1 field 字段标签

filed标签用于配置字段信息,该标签中包含如下属性:

  • name: 字段名称,值要求唯一
  • type: 字段数据类型

支持哪些常用的数据类型
string 字符串
int, long 整数
float, double 浮点数
date 日期时间
bool 布尔类型
text 文本类型
binary 二进制类型

  • indexed: 当前字段是否创建索引,默认值为true

这里的索引指的是什么?
因为solr使用倒排索引,所以创建索引的含义,就是将字段值包含在倒排索引中,也就是用该值分词创建倒排索引,从而支持基于该字段的搜索和过滤。

创建索引的好处和坏处?
好处是提高了查询小了,坏处当然是增加了存储空间占用,而且当字段值本身很大时,创建索引也会带来一定的性能损耗。因此在指定索引字段时,也要综合考虑。

  • stored: 当前字段是否存储,默认为true

是否存储,指的是存储到哪里?
配置该字段的值是否存储到solr本身的存储库中,如果存储,那么当查询后的显示就不需要再查询数据源了,对于只需要排序、索引的字段,则可以设置为false来节约空间

比如设置indexed=true, stored=false, 则表示该字段值用于创建索引,但不做存储吗?
是的,该字段值不做存储,但是值会被分词用于创建倒排索引,如此当查询的结果需要再显示该字段时,就需要再次查询数据源来显示,而查询数据源本身是相对较慢的操作

这里的数据源到底指的是什么?
solr的数据源可能是数据库、文件、接口等,比如配置了solr数据是从mysql通过dataimport同步过来了,那么数据源就是mysql,查询数据源就表示通过sql再查一遍mysql,所以速度自然就慢

stored=true的好处和坏处?
好处是提高读取性能,直接存储在solr了,无需再从数据源获取,提高查询效率;坏处当然是占用磁盘空间,对于海量的数据时,如果不需要显示,仅仅只是做索引则不用存储,存储也意味着更高的磁盘、网络IO

  • docValues: 是否启用点列存储当前字段值,默认为false, 当需要字段做排序或者聚合查询时需要设置为true

什么是点列存储?
点列存储(也叫列存储)是倒排索引之外的一种存储结构,我们更加熟悉的是数据库的行存储,但实际上像oracle,sqlserver都已经在支持列存储,列存储是指的是按照列来进行分组存储
比如我们有如下的几行数据

nameagesexaddressschool
张三28广州市xxx路南京大学
李四18北京市xxx路湖南大学
丽丽19福州市xxx路江南大学

这几个数据按行存储的话,在磁盘中的存储方式如下所示
同一行的数据是放在一起的
在这里插入图片描述
而列存储的话,就是同一列的数据放在一起
在这里插入图片描述
这样存储的好处在于当我们需要对年龄进行分组的时候,我们就不需要把全部数据查询一遍,而只需要找到对应列的位置,然后将这一连续空间的数据查询出来,进行聚合操作即可
这样的存储方式,极大的方便了针对数值型字段聚合、重复度高的字段分组、需要排序的字段的查询操作
并且联想一下,针对数值列,重复度高的列,我们还可以进行压缩操作,更加节约存储空间

上述图形中,姓名、地址、学校这些字段也按列存储了,是不是造成浪费了?
其实有这个问题,你大概率是陷入了误区,上述是为了给大家展示按列存储的物理结构,实际的操作时,我们是按需定义的,不要忘记这个属性是在field标签下的,也就是说他是针对某一列设置是否按列存储,所以如果不需要的字段,你不设置即可

  • multiValues: 字段值是否可重复,或者说是否为多个值,默认为false。一般用于数组字段

比如如下的数据中,技能字段skills就是一个数组类型,就需要用multiValues=true标识

{
  "name": "张三",
  "age": 28,
  "sex": "男",
  "address": "广州市xxx路",
  "school": "南京大学",
  "skills": [
      "Java",
      "Python",
      "C++",
      "数据结构与算法"
  ]
}

默认字段

基于以上的属性我们就可以自定义字段了,但同时solr也提供了一些默认的字段,也称为域

    <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
 
    <field name="_version_" type="plong" indexed="false" stored="false"/>

    <field name="_root_" type="string" indexed="true" stored="false" docValues="false" />
  
    <field name="_nest_path_" type="_nest_path_" /><fieldType name="_nest_path_" class="solr.NestPathField" />

    <field name="_text_" type="text_general" indexed="true" stored="false" multiValued="true"/>

如上所示,其中包括:

  • id: 文档的唯一标识符,可以指定为数据源中的唯一索引字段
  • _version_: 版本号,用于并发控制,每次更新文档,版本值都会自动递增
  • _root_: 用于嵌套文档结构,表示潜逃文档所属的最外层文档
  • _nest_path_: 用于嵌套文档结构,表示嵌套文档在文档中的路径,可以根据该路径来查询嵌套文档
  • _text_: 文档的主要内容,用于全文检索

假设有如下文档值:

{
  "id": "001",
  "title": "Solr 学习笔记",
  "content": "这是一篇关于 Solr 的学习笔记,包含了 Solr 的介绍、安装、配置和使用等内容。"
}

则对应的这几个字段的值是:

{
  "id": "001",        // 文档唯一标识符
  "_version_": 1,     // 并发控制版本号
  "_root_": "001",    // 嵌套文档根节点(此处与id相同)
  "_nest_path_": "",  // 嵌套文档路径(顶级文档为空字符串)
  "_text_": [         // 全文检索内容
    "这是一篇关于 Solr 的学习笔记,包含了 Solr 的介绍、安装、配置和使用等内容。",
    "Solr 学习笔记"
  ]
}

比如有点赞信息时,就会引入嵌套文档

{
  "id": "002",
  "title": "Solr 文档结构示例",
  "content": "这是一篇 Solr 文档嵌套结构的示例。",
  "_root_": "002",   // 根节点为自己
  "_nest_path_": "", // 初始情况下为空字符串
  "_text_": [
    "这是一篇 Solr 文档嵌套结构的示例。",
    "Solr 文档结构示例"
  ],
  "like": [          // 嵌套文档:点赞
    {
      "id": "u001",
      "user_name": "Tom",
      "_root_": "002",          // 父文档ID
      "_nest_path_": "/like",   // 嵌套路径为 /like
      "_text_": ["Tom"]
    },
    {
      "id": "u002",
      "user_name": "Jack",
      "_root_": "002",          // 父文档ID
      "_nest_path_": "/like",   // 嵌套路径为 /like
      "_text_": ["Jack"]
    }
  ]
}

1.2 dynamicField 动态字段标签

动态字段是用来做什么的?
当我们出现部分字段名都是类似的,且表示相同的含义时,比如:name_1, name_2, name_3 ,如果有成百上千个这样的字段需要定义,还是很麻烦的,可能你觉得不会有这样的场景,但是在搜索引擎的业务场景下,存在大批量字段是比较常见的事情。

这个时候,我们就希望能有一个类似通配符匹配配置的模式,来帮助我们批量定义字段,于是就出现了动态字段,比如上述的name_1, name_2, name_3 我们就可以定义为:

<dynamicField name="name_*"  type="pint"  indexed="true"  stored="true"/>

动态字段只能有前缀和后缀两种匹配模式,用*来表示

同时需要注意,在solr中,只有在managed-schema文件中配置过的字段,才能在查询时使用,这与数据库的逻辑是一致的,没有定义过的字段,直接使用就会报错"字段未找到"

1.3 uniqueKey 唯一主键标签

solr中默认使用id作为唯一主键,更新和新增时就通过唯一主键是否存在来决定

1.4 copyField 复制字段标签

复制字段的意思就是将一个或多个字段的值填充到另一个字段中,主要用来:

  • 将多个字段填充到一个字段方便搜索;

如果目标字段中已经有自己的数据,那么会把复制字段的内容作为附加值添加到目标字段的内容中,从而实现更加全面的搜索覆盖

<copyField source="name" dest="search_total"/>
<copyField source="content" dest="search_total"/>
<copyField source="title" dest="search_total"/>
  • 对同一个字段定义不同的分词器,用于不同的搜索场景

比如将某字段值,定义英文分词器,中文分词器,西巴牙语分词器,以应对不同语种的搜索场景

<copyField source="name" dest="name_english"/>
<copyField source="name" dest="name_chinese"/>

1.5 fieldType 字段类型标签

filedType标签主要用于定义字段的分词器、过滤器,实现为不同字段定义不同的分词、过滤器

相当于是定义一个字段类型,然后在类型中指定使用的类,然后在field标签中就可以直接使用这个自定义的类型

如下示例,就定义了一个类型my_text,定义了两个分析器,一个用于索引(index),一个用于查询(query),都是用StandardTokenizerFactory作为默认的分词器,StopFilterFactory作为过滤器,分别用于去除标点和停用词。不同的是查询时额外使用了SynonymGraphFilterFactorysynonyms.txt获取同义词

PS:

1、solr有哪些分词器和过滤器,我们将在后续讲解,或者大家也可自行拓展搜索,中文中还有常用的中文分词器——IK分词器
2、不清楚同义词、过滤器、停用词作用的,因为是搜索引擎的基础概念,大家可自行搜索,如果仍不清楚,可留言提问

<fieldType name="my_text" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
    <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" />
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

filedType标签中常用的属性如下:

  • name: 定义类型名称
  • class: 定义类型使用的class类,比如text类型的用的就是solr自带的TextField类
  • positionIncrementGap 属性指定了位置增量间隔,用于多值字段在索引中处理位置信息,默认是0,也就是每个分词之间存储的间隔

默认为0的话,比如这样的文档:

<doc>
	<filed name="id">1</field>
	<filed name="content">wu quick study</field>
	<filed name="content">solr study</field>
</doc>

如果针对content字段设置的fieldType指定了默认positionIncrementGap=0,那么content的位置编号就是:

位置编号文本
1wu quick study
2solr study

如果设置的positionIncrementGap=10,则位置编号为,及文本不是连续存储的

位置编号文本
1wu quick study
11solr study

设置positionIncrementGap的好处和坏处?
设置后可以控制多值字段不同值之间的位置增量,这样solr可以更加准确的计算匹配文档和查询相关度,从而计算结果排名,简言之就是查询的结果排名计算更加准确。当然他的坏处就是占用的空间变大,使得索引变大,那么查询性能就受到影响了

其次,fieldType也支持filed中的以下标签:

indexed:是否可以被索引,默认为 true。
stored:是否可以被存储,默认为 true。
multiValued:是否为多值字段,默认为 false。
docValues:是否启用 DocValues,默认为 false。
termVectors:是否启用 TermVectors,默认为 false。

2. 总结

今天,我们针对schema标签的详解就到此结束了,是不是感觉标签属性很多,记不过来,其实没关系,实际使用部分标签是用不到的,我们还可以根据模版参考配置,无需专门背诵,根据实际场景,多写几遍,自然就记住了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/23542.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV——最小外接矩形

目录 一、主要函数二、代码实现三、结果展示 一、主要函数 cv::RotatedRect cv::minAreaRect(const cv::Mat& points );emspminAreaRect 函数用于计算给定点集的最小外接矩形。该矩形的长和宽是可以任意旋转的&#xff0c;因此被称为旋转矩形。 points &#xff1a;是一个…

article-码垛机器人admas仿真

按照运动学仿真的类似步骤为机器人添加材料、运动副和关节驱动&#xff0c;给机器人手腕末端施加50N最大负载&#xff0c;仿真模型如图5-17。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AXYQVZPq-1684936426972)(data:image/svgxml;utf8, )] 图…

Python实现ACO蚁群优化算法优化BP神经网络回归模型(BP神经网络回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蚁群优化算法(Ant Colony Optimization, ACO)是一种源于大自然生物世界的新的仿生进化算法&#xff0c…

Qt自定义的ColorDialog--仿QColorDialog

Qt已经有了色板选择&#xff0c;但是它使用QDialog形成的&#xff0c;每次调用基本上都成了点一个按钮&#xff0c;谈一个模态框&#xff0c;选择好颜色之后再关掉模态框。 但是&#xff0c;如果想将颜色选择板放在窗口上&#xff0c;并不会有模态的功能就会比较麻烦&#xff…

docker安装mysql8.0.33

1 从docker仓库中拉去mysql 8.0 docker pull mysql:8.0如果使用 docker pull mysql 默认拉取的是最新版本的mysql 上面我拉去的是8.0的版本&#xff0c;最后拉取过来的是8.0.33 如果有想要指定的版本&#xff0c;可以直接写指定版本&#xff0c;如&#xff1a; docker pull my…

pytorch:nn.ModuleList和nn.Sequential、list的用法以及区别

文章目录 在构建网络的时候&#xff0c;pytorch有一些基础概念很重要&#xff0c;比如nn.Module&#xff0c;nn.ModuleList&#xff0c;nn.Sequential&#xff0c;这些类我们称为为容器&#xff08;containers&#xff09;&#xff0c;可参考containers。本文中我们主要学习nn.…

【Python】正则表达式应用

知识目录 一、写在前面✨二、姓名检查三、解析电影排行榜四、总结撒花&#x1f60a; 一、写在前面✨ 大家好&#xff01;我是初心&#xff0c;希望我们一路走来能坚守初心&#xff01; 今天跟大家分享的文章是 正则表达式的应用 &#xff0c;希望能帮助到大家&#xff01;本篇…

把字节大佬花3个月时间整理的软件测试面经偷偷给室友,差点被他开除了···

写在前面 “这份软件测试面经看起来不错&#xff0c;等会一起发给他吧”&#xff0c;我看着面前的面试笔记自言自语道。 就在这时&#xff0c;背后传来了leder“阴森森”的声音&#xff1a;“不错吧&#xff0c;我可是足足花了三个月整理的” 始末 刚入职字节的我收到了大学室…

Windows 10 X64 内核对象句柄表解析

fweWindows 很多API函数都会创建和使用句柄(传入参数)&#xff0c;句柄代表一个内核对象的内存地址&#xff0c;每个进程都有一个句柄表&#xff0c;它保存着进程拥有的句柄&#xff0c;内核也有一个句柄表 PspCidTable&#xff0c;它保存着整个系统的句柄。 ExpLookupHandleTa…

DNS风险分析及安全防护研究(一):DNS自身风险分析(中科三方)

作为互联网上的一项基础服务&#xff0c;DNS在网站运行中起到了至关重要的作用&#xff0c;然而其安全性在很长一段时间内都没有得到足够的重视。DNS采用不可靠的UDP协议&#xff0c;安全性具有较大的漏洞&#xff0c;攻击者很容易利用这些漏洞发动攻击&#xff0c;从而引起一些…

华为设备这14个广域网命令,值得每位做广域网业务的网工收藏!

你好&#xff0c;这里是网络技术联盟站。 华为设备广域网命令是网络管理员在运维过程中常用的一类命令。该命令集涵盖了DCC配置命令、PPP配置命令、MP配置命令、PPPoE命令、ATM配置命令、帧中继配置命令、HDLC配置命令、LAPB配置命令、X.25配置命令、IP-Trunk配置命令、ISDN配…

Java 与数据结构(6):快速排序

ChatGPT 中文指南(大全) 内容包含&#xff1a;如何开通chatgpt、chatgpt的同类站点、prompts 、AI绘图、ChatGPT 工具、相关报告论文、ChatGPT应用项目等 链接&#xff1a;ChatGPT 中文指南(大全) 指令指南&#xff0c;精选资源清单&#xff0c;更好的使用 chatGPT 让你的生产力…

详解如何使用LAMP架构搭建论坛

文章目录 1.LAMP概述2.编译安装Apache httpd服务1.关闭防火墙&#xff0c;将安装Apache所需软件包传到/opt目录下2.安装环境依赖包 3.配置软件模块4.编译及安装5.优化配置文件路径&#xff0c;并把httpd服务的可执行程序文件放入路径环境变量的目录中便于系统识别6.添加httpd系…

复杂的C++继承

文章目录 什么是继承继承方式赋值规则继承中的作用域&#xff08;隐藏&#xff09;子类中的默认成员函数需要自己写默认成员函数的情况 继承与友元及静态成员多继承菱形继承菱形继承的问题菱形虚拟继承 继承和组合 面向对象三大特性&#xff1a;封装继承和多态。封装在类和对象…

(四)调整PID控制器参数的指南

一、控制系统设计快速入门和环境 首先确定一下控制任务。快速、精准地控制&#xff0c;必要的稳定性&#xff0c;时域&#xff08;上升时间、超调等&#xff09;&#xff0c;频域&#xff08;带宽、阻尼比&#xff09;然后明白控制系统特点。类积分器&#xff1f;开环稳定性、高…

注解实现自动装配

要使用注解须知&#xff1a; 1.导入约束 context约束 2.配置注解的支持 官方配置文件 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/…

详解知识蒸馏原理和代码

目录 知识蒸馏原理概念技巧举例说明KL 散度及损失 KD训练代码导入包网络架构teacher网络student网络 teacher网络训练定义基本函数训练主函数 student网络训练&#xff08;重点&#xff09;理论部分定义kd的loss定义基本函数训练主函数 绘制结果teacher网络的暗知识softmax_t推…

C4d Octane渲染器内存满、卡顿、崩溃、缓慢、updating解决办法

最近碰到Octane渲染动画序列&#xff0c;总是会渲染一段时间后卡在某一张图片上&#xff0c;图片查看器左下角一直显示updating。 偶然发现在C4D界面点击octane工具栏的设置&#xff0c;它又会开始渲染&#xff0c;但渲染一些序列帧后又会卡在一张图上显示updating 点击octane工…

【Netty】 工作原理详解(十一)

文章目录 前言一、Netty 模型二、代码示例2.1、引入Maven依赖2.2、服务端的管道处理器2.3、服务端主程序2.4、客户端管道处理器2.5、客户端主程序2.6、测试运行 总结 前言 回顾Netty系列文章&#xff1a; Netty 概述&#xff08;一&#xff09;Netty 架构设计&#xff08;二&…

【Python]】地图热力图如何绘制?(含源代码)

文章目录 一、问题引入 & 使用地图的说明1.1 问题的引入1.2 使用地图的说明 二、方法1三、方法2 一、问题引入 & 使用地图的说明 1.1 问题的引入 我们有一个中国各省份的数据集&#xff0c;要求绘制地图热力图&#xff0c;该怎么实现呢&#xff1f; 部分数据集如下&…