1 创建索引
完成搜索的第一步是建立搜索数据集的对象,即建立索引。在定义酒店的搜索需求时,应该包括的字段有酒店标题、所属城市和房价等。对于酒店标题来说,需要按照用户输入的关键词进行模糊搜索,因此应该定义成文本(text)型;对于所属城市来说,只需进行相等与否的判断,定义成普通的关键词类型(keyword)即可;对于房价来说,只需进行大小比较的判断,因此定义成数值中的双精度浮点型。假设使用默认的分片数和副本数,整体的索引创建语句如下:
PUT /hotel
{
"mappings":{
"properties":{ //指定字段名称及其数据类型
"title":{
"type":"text" //title字段为text类型
},
"city":{
"type":"keyword" //city字段为keyword类型
},
"price":{
"type":"double" //price字段为double类型
}
}
}
}
2 写入文档
为方便演示后面的搜索功能,hotel索引创建后,需要在索引中填充一些数据。例如,在目标索引中写入下面的数据:
POST /hotel/_doc/001
{
"title":"好再来酒店",
"city":"青岛",
"price":578.23
}
执行上述命令后,在索引中创建了一条ID为001的文档。
3 根据_id搜索文档
GET /hotel/_doc/001
{
"_index" : "hotel", //索引名称
"_type" : "_doc",
"_id" : "001", //文档ID
"_version" : 1, //文档版本
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : { //文档内容
"title" : "好再来酒店",
"city" : "青岛",
"price" : 578.23
}
}
从上面显示的结果中可以看出搜索的一些元数据,如是否找到、索引名称、文档ID值、文档版本等,在_source中展示了命中的文档的原始数据,这和1.5.2节写入的数据是相同的。
4 根据一般字段搜索文档
在ES中进行搜索时需要用到query子句,其请求形式如下
GET /${index_name}/_search
{
"query": { //查询内容
…
}
}
query子句可以按照需求填充查询项。假设按照城市进行搜索,把酒店文档搜索出来。因为只需要进行文本是否相等的判断,所以需要用到term搜索,在后面的章节中将会详细介绍term搜索,此处只进行简单使用
GET /hotel/_search
{
"query": {
"term": {
"price": { //根据价格搜索文档
"value": 578.23
}
}
}
}
{
"took" : 1,
"timed_out" : false,
"_shards" : { //命中的分片信息
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : { //命中的文档总数
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0, //命中文档中的最高分
"hits" : [ //命中文档集合的信息
{
"_index" : "hotel", //文档所在索引
"_type" : "_doc",
"_id" : "001", //文档ID
"_score" : 1.0, //文档分值
"_source" : { //文档内容
"title" : "好再来酒店",
"city" : "青岛",
"price" : 578.23
}
}
]
}
}
由上面的结果可以看出,ES不仅返回了搜索的文档结果,而且对结果进行了打分计算,因为本例使用的是比较简单的搜索,并没有使用其核心的计算公式,所以得分是1。
5 根据文本字段搜索文档
欢迎进入真正的搜索世界!前面的搜索功能传统的关系型数据也可以胜任,但是对文本进行模糊匹配并给出匹配分数这一功能是搜索引擎所独有的。此处使用match搜索对某个字段进行模糊匹配,按照标题进行模糊搜索,示例如下:
GET /hotel/_search
{
"query": {
"match": { //根据title字段搜索
"title": "再来"
}
}
}
{
…
"max_score" : 0.5753642, //命中文档中的最高分
"hits" : [ //命中文档集合的信息
{
"_index" : "hotel",
"_type" : "_doc",
"_id" : "001",
"_score" : 0.5753642,
"_source" : {
"title" : "好再来酒店",
"city" : "青岛",
"price" : 578.23
}
}
]
}
}
由上面的结果可以看出,ES对结果进行了打分计算,此处使用了对文本打分计算的算法。关于算法的详细介绍请参考后面章节。