Field 域使用|学习笔记

简介: 快速学习 Field 域使用

开发者学堂课程【Lucene 知识精讲与实战(上)  Field 域使用】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/700/detail/12336


Field 域使用


内容介绍

一、简介

二、代码编写

三、执行结果


一、简介

field 域的类型,就是在创建索引的时候,为每个域都分配了一个类型,叫做文本类型。

当初创建索引库的时候,在文档中添域,域的类型全都设置成了文本类型,但其实域有很多类型,选择使用什么样的域就是要研究的内容。

 

Field类

数据类型

Analyzed是否分词

Indexed 是否索 引

Stored是否存储

说明

StringField(FieldName,

FieldValue,Store.YES))

字符串

N

Y

Y或N

Field用来构建一个字符串Field,但是不会进行分词,会将整个串存储在索引中,比如(订单号,身份证号等)是否存储在文档中用Store.YES或Store.NO决定

FloatPoint(FieldName,FieldValue)

Float型

Y

Y

N

Field用来构建一个Float数字型Field,进行分词和索引,不存储,比如(价格) 存储在文档中

DoublePoint(FieldName, DoubleValue

Double型

Y

Y

N

DoublePoint(FieldName, Double   N Field用来构建一个Double数字型Field

LongPoint(FieldName,FieldValue)

Long型

Y

Y

N

这个Field用来构建一个Long数字型Field,进行分词和索引,不存储。

IntPoint(FieldName, FieldValue)

Integer型

Y

Y

N

这个Field用来构建一个Integer数字型Field,进行分词和索引,不存储。

StoredField(FieldName,

FieldValue)

重载方法,支持多种类型

N

N

Y

这个Field用来构建不同类型Field不分析,不索引,但要Field存储在文档中

TextField(FieldName, FieldValueStore.NO)或TextField(FieldName,reader)

字符串或流

Y

Y

Y或N

如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略.

NumericDocValuesField(FieldName, FieldValue)

数值

-

-

-

配合其他域排序使用

表格中列出了部分它的域的类型不是全部是部分。首先先竖着看 field 的类中域的一个类型,叫做数据类型。数据类型表示它对应 Java 里边到底对应哪些类型,比如说字符串型等等。

先来看使用是字符串的,然后还有 float 类型, Double float,是否分词,是否索引,是否存储,看它的值是 yes 或者是 no,如果只有一个选项,则不能改,no 就是不分词。

确定是否分词、是否索引,是否存储,就要来研究分词的目的是什么,索引的目的是什么,存储的目的是什么。也就知道在该怎么去选择什么样的 field 的域了。

分词的目的是为了索引,索引的目的查询出来,索引是通过全文检索法来查的。在路线中没有方式方法,不索引就查询不出来,索引了才能进行查询。

分词举个例子,比如要查询,首先商品名称,根据商品名称作为查询字段,想查商品名,时候商品名分词了有没有意义,比如说华为手机,可以分成华为,手机,所以说这种要索引。再比如说一篇文章的商品描述,都是要分词的,如果说商品ID是唯一标识,ID 是数据库的组件字段,并且全都是数字,它能唯一的去掉确定这么一条数据,所以它作为一个整体来讲不分词。要根据 ID 查不分词。如果不想根据ID查询,就可以不索引。分词如果是一个整体就不分了,不是一个整体,就可以分词。如果说不想根据某一个字段查,不管它有没有意义都可以不用分词了。

索引的目的是为了查询,根据某一个字段要查。不查,那就不索引。比如图片的路径,在京东上买东西,没有根据图片路径来查的,一般是直接输入要查这商品品牌的名,这些东西这些关键字没有说根据一个图片路径来进行查询的。所以索引就是为了查询,不索引就可以不查询。

索引了要查询,还要分为分不分词,分词有意义则分,分词无意义的比如说订单号、身份证、商品ID,这些他们是一个整体的,分开之后没有什么意义,可以不分词。不进行查询、不进行索引的,也可以不分词,其他的想要查询之后并且有意义,就需要分词。

是否存储管的是能不能显示出来,也就是说虽然不根据图片路径进行查询,但是要把它展示到页面上,然后给消费者给用户来看商品的事例图片长什么样,就要如果页面上它不需要展示图片,不准备展示商品的图片,就可以不存储。也就是说虽然能查出来,但是一展示它的结果是什么是no。这是关于存储的目的。也就是说分词和索引它影响的是lunk是索引的内容,而是否存储影响的是文档中的内容。

如果说文档中,存储的时候设置成某一个域不存储,在文档中,设置完不存储之后,域就会显示域值是null,查完之后找到文档看它的结果是 no,什么都没有,

是否分词,是否索引,是否存储,在对于域中要进行改造,给他找到适合的匹配的域进行改造。


二、代码编写

//创建域对象并且放入文档对象中

首先分析一下 ID 域中,ID 它是的一个业务组件,比如说在的商品的表中,它是组建 ID 唯一能确定某一条数据,从三点来改造它。即是否分词,是否索引,是否存储,都从这三点来分析,分析完之后就知道怎么去选择它对应的域了。每个域都需要经过这三点分析,都写上写完之后一个来分析首先来看 ID,

ID 作为组件,有可能根据组件来把它查询出来,要查询就必须所以写,如果根据 ID组件不索引是查不了的,是否分词,作为组件是一串数,把它切分成一个的数字没有意义。如果没有意义,就可以不分词,因为组建分词后无意义。

如果说像身份证号,每个人的身份证号是都是唯一的,是一串数字,如果给它切分词,每一个数字单独拿出来,没有任何意义,什么也代表不了。所以说像这样唯一的东西,要看需不需要把它的ID展示出来,像京东,商品的 ID 可能说展示出来也没什么用,消费者看到也没什么用,但是拿到 ID 就可以通过 ID 跟数据库的数据有关联关系,或可以通过组件 ID 数据库中办一些其他的业务上的事情。

所以说对于 ID 一般还是存储起来比较好,因为存储起来,它不浪费很多的存储空间,因为 ID 比较短。如果不存,等用到的时候找不到。虽然能查到,但是展示不出来组件 ID 是多少,是因为组件ID比较特殊。所以存储后才可以获取到 ID 具体的内容。看对照着表格,看还有没有跟它同类型的,没有,则使用fleid,改造一下。

是否分词:否,因为主键分词后无意义

是否索引:是,如果根据 id 主键查询,就必须索引

是否存储:是,因为主键 id 比较特殊,可以确定唯一的一条数据,在业务上一般有重要所用,所以存储

存储后,才可以获取到 id 具体的内容

document.add(new StringField("id",sku.getid(),Field.store.YES));

再来看名称字段,需要根据名称来查,比如查询名称中包含手机的,包含华为的,是包含关键字的

是否分词:是,因为名称字段需要查询,并且分词后有意义所以需要分词

是否索引:是,因为需要根据名称字段查询

是否存储:是,因为页面需要展示商品名称,所以需要存储

document.add(new Textfield("name",sku.getName((),Field.Store.YES));

价格如果要查询,需要查询以上的多少钱,以下的多少钱,可以根据范围进行查询。如果根据范围查询,看他这些关于数值类型的FloatPoint(FieldName,FieldValue)、DoublePoint(FieldName, DoubleValue)、LongPoint(FieldName,FieldValue)这些数值类型的,是否分词,所以是全都写的是 yes,是改不了的。

价格类型:价格是数值,数值类型要通过范围查询,必须索引。需要根据价格进行范围查询,索引了之后会发现在表格中,这些数值类型全都是分词的,全都是 yes,假如说12.5、1000元等等这种数值,切分词没有意义,分不分词也要分词。 是 lucene 底层算法规定切分词,不是说把100元切分成1,0,0.根据 lucene 底层算法规定,如果根据价格范围查询,必须分词,没有办法改。

一个电商网站,展示一个商品,价格肯定需要展示。所以说查询完之后必须要展示出来,必须存储。所以说也要选择yes,因为页面需要展示,价格需要展示。

看一下表格, yes 比较多,FloatPoint(FieldName,FieldValue)、DoublePoint(FieldName, DoubleValue、LongPoint(FieldName,FieldValue)这些数值范围都是 no,是说明不存储,StoredField(FieldName,

FieldValue)是存储,但是它是不分词,也是不索引的。

在存储价格的时候,跟早期版本不太一样,早期版本,如果说存储这种价格,然后数根据数值范围查询,直接用 IntPoint(FieldName, FieldValue)等等。

在最新版本的的7.7.2版本中,API 改了。首先要选择一个这种数值的 point 这些域来进行使用,使用完了它是不存储,不存储可以用StoredField(FieldName,

FieldValue)来进行存,所以说对于这种价格它的处理是比较特殊的。

原来在的sku里边,价格是 int 类型,所以就用 Intpoint 来进行存。后边括号去掉,传的参数也不是三个参数了,两个参数变成int类型的,关于价格关于数值范围查询的,字段是比较特殊的。

是否分词:是(因为 lucene 底层算法规定,如果根据价格范围查询,必须分词)

是否索引:是,需要根据价格进行范围查询,所以必须索引

是否存储:是,因为页面需要展示价格

document.add(new IntPoint("price",sku.getPrice()));

document.add(new StoredField("price",sku.getPrice()));

关于图片,存的不是图片内容,是图片的地址。一般如果做电商,是不需要根据图片地址进行查询的,因为查询的都是某一个商品,所以说不查询就可以不索引,不索引就查不出来了。因为不需要根据图片地址入境查询,不查询不要分词。所以说否是因为不查询。分词和索引影响索引文件,存储影响的是文档,是否存储这一部分就看页面,页面上一般是要展示图片,所以是要存储的。索引和分词这两个是有关系的,索引分词和存储无关,它影响的是文档内容,而这两个影响的是索引内容。

因为页面需要展示图片,所以说给它存起来。特殊情况可以根据别的字段,根据别的域查出来结果,在结果中如果要展示,就可以把它可以拿到展示出来。如果说要不存,图片要展示,它就是 null。

是否分词:否,因为不查询,所以不索引,因为不索引所以不分词

是否索引:否,因为不需要根据图片地址路径查询

是否存储:是,因为页面需要展示商品图片

document.add(new StoredField("image",sku.getImage()));

分类名称要根据大家电小家电等等,这样可以进行索引才能查出来。

关于分词分类,大家电小家电等等,它是一个专有名词,某一个分类它是一个专有名词,它如果是一个整体,就不分词。如果说要认为它不是一个专有名词,可以把它切碎了,就可以分词,所以分词和存储看页面要不要展示分类名。如果展示,就得存储,因为页面需要展示分类。

是否分词:否,因为分类是专有名词,是一个整体,所以不分词

是否索引:是,因为需要根据分类查询

是否存储:是,因为页面需要展示分类

document.add(new StringField("categoryName",sku.getCategoryName(),Field.Store.YES));

品牌名要根据品牌进行查询的,查华为,查苹果等品牌

品牌它是专有名词或者不是专有名词,需要看情况。比如华为是一个专有名词,所以说认为不分词比较好,因为它是一个专有名词,是一个整体。如果说要切成华和为将什么也代表不了,所以说不分词。因为品牌是专有名词,名词是一个整体,所以不分词。

再来看存不存储,页面上查询出来东西要展示它的品牌是否需要分词。

是否分词:否,因为品牌是专有名词,是一个整体,所以不分词

是否索引:是,因为需要根据品牌进行查询

是否存储:是,因为页面需要展示分类

document.add(new TextField("brandName",sku.getBrandName(),Field.Store.YES));

 

三、执行结果

通过改造后的这些域重新来执行,测试一下,重新执行完之后,他会重新创建索引库里边的内容,然后再用 lunk 小工具来进行查看,查看它里边跟以前都有什么变化,都有什么不同。

image.png

执行完成之后重新点击 lunk 小 工具打开索引库的位置没变, ID 没有什么变化,因为它是一个整体不切分词,名称名称跟以前也没有什么太大变化。

品牌名是一个整体,不分词,所以用 field 的,认为一个整体,不分词,华为、南极人,森马等等,这是都是整个的一个品牌名。

分类名也是一个整体,是不切分词的。

图片点击后发现什么反应都没有,但是右边点中它没有反应,展示数据还是上边分类的,说明数据没有刷新。切分出来的值为0。

价格是一个数字,数字要进行数值的范围查询,因为买东西要查多少钱以上,多少钱以下的。然后设置的不分词,因为lucece底层算法规定,如果要根据数值范围查询,必须分词,但是看不出来分词。这是它底层算法的原因,改不了,虽然分了,但是看不出来。

文档分页跟以前是没有太大变化,原因是存储。如果要设置不存储,可能展示不出来。根据索引查出来是找文档,然后找出来文档,把文档先展示出来。如果不存储的域,则无法展示。

 

相关文章
|
2月前
|
JavaScript 前端开发 安全
文档域(document.domain)
文档域(document.domain)
|
2月前
|
监控 UED
深入理解Call-ID头字段的重要性
【8月更文挑战第24天】
82 0
|
5月前
list如何将自己实体的字段值赋给另外一个List实体中的相同字段
list如何将自己实体的字段值赋给另外一个List实体中的相同字段
122 0
【Word】利用域代码快速实现自定义编号
【Word】利用域代码快速实现自定义编号
196 0
|
Shell 数据安全/隐私保护 Windows
导出域内所有hash--笔记(建议收藏)
-导出ntds.dit(域控服务器上操作): 存在域控制器的c:\windows\ntds\ntds.dit中。
267 0
|
前端开发 Java Spring
Spring MVC框架:第四章:属性域使用(request域、session域、application域)
Spring MVC框架:第四章:属性域使用(request域、session域、application域)
115 0
Spring MVC框架:第四章:属性域使用(request域、session域、application域)
|
数据库 C#
Entity Framewor简单属性映射
Entity Framewor简单属性映射
96 0
Entity Framewor简单属性映射
|
API 数据库
Entity Framework复杂类型属性映射
Entity Framework复杂类型属性映射
143 0
Entity Framework复杂类型属性映射
|
机器学习/深度学习 人工智能 数据库
零示例学习中的映射域迁移 (projection domain shift) 问题
本文介绍了两种解决零示例学习中的映射域迁移问题的方法 AEZSL 和 DAEZSL 。
819 0