白话Elasticsearch01- 结构化搜索之使用term query来搜索数据

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 白话Elasticsearch01- 结构化搜索之使用term query来搜索数据

20190512121336145.png20190512110631263.png20190806092132811.jpg

需求描述


这个系列我们来跟着中华石杉老师来系统的学习下ES

课程地址: https://www.roncoo.com/view/55

需求背景: 一个普通的论坛,根据用户ID、是否隐藏、帖子ID、发帖日期来搜索帖子


ES版本


我这里用的版本是ES6.4.1 , 只要是5.X以上的版本都使用。目前ES的版本已经到了7.0.


Kibana用的也是对应的kibana-6.4.1-windows-x86_64


Term Filter 不推荐使用了,推荐使用 Term Query


https://www.elastic.co/guide/en/elasticsearch/reference/6.4/query-dsl-term-filter.html#query-dsl-term-filter


20190512214644648.png

6.4版本的 Term Query说明

https://www.elastic.co/guide/en/elasticsearch/reference/6.4/query-dsl-term-query.html


_bulk 批量写几条数据

POST /forum/article/_bulk
{ "index": { "_id": 1 }}
{ "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 2 }}
{ "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" }
{ "index": { "_id": 3 }}
{ "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 4 }}
{ "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }


_bulk 用法


BULK API官网说明: https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html


简单说下_bulk api , 批量执行,对执行的json串有严格的格式要求,不要格式化JSON串


20190512095420722.png

返回结果分析

直接在kibana的DevTool中执行上述JSON即可


20190510220626895.png


返回结果

#! Deprecation: the default number of shards will change from [5] to [1] in 7.0.0; if you wish to continue using the default of [5] shards, you must manage this on the create index request or with an index template
{
  "took": 1581,
  "errors": false,
  "items": [
    {
      "index": {
        "_index": "forum",
        "_type": "article",
        "_id": "1",
        "_version": 1,
        "result": "created",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "_seq_no": 0,
        "_primary_term": 1,
        "status": 201
      }
    }
    ......篇幅原因,省略其他三个的显示
    }
  ]
}


结果说明:


20190512095731171.png

took: query的时间,不包括fetch

再看下_shard节点下的total和successful信息


total: 2 一共两个shard需要执行 ,一个primary shard ,一个

replicas shard . 因为我们在同一个机器上起的(默认使用的 主shard 5 副本shard 1的配置)。 主shard 和 副本shard不能在同一个node上,所以该副本shard并未分配,所以这里successful 为1 。

通过head插件我们也可以窥之一二



20190512101752598.png

字段Dynamic Mapping


POST /forum/article/_bulk es会自动创建名为forum的index和名为article的 type

未提前设置field类型的话,es会通过Dynamic Mapping的方式来自动映射字段类型 ,我们来看下 GET /forum/_mapping/article

执行:
GET /forum/_mapping/article
返回:
{
  "forum": {
    "mappings": {
      "article": {
        "properties": {
          "articleID": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "hidden": {
            "type": "boolean"
          },
          "postDate": {
            "type": "date"
          },
          "userID": {
            "type": "long"
          }
        }
      }
    }
  }
}


Dynamic Mapping 中 text类型的字段


我们重点来看下 articleID


es 5.x版本中对于type=text,默认会设置两个field, 一个是field本身,比如articleID,就是分词的, 另外一个,就是field.keyword,在这里就是用的话articleID.keyword,默认不分词,最多保留256个字符("ignore_above": 256)

articleID.keyword,是es新版本内置建立的field,就是不分词的。所以一个articleID过来的时候,会建立两次索引,一次是自己本身,是要分词的,分词后放入倒排索引;

另外一次是基于articleID.keyword,不分词,保留256个字符最多,直接一个字符串放入倒排索引中。


所以term filter,对text过滤,可以考虑使用内置的field.keyword来进行匹配。但是有个问题,默认就保留256个字符。所以尽可能还是自己去手动建立索引,指定not_analyzed吧。在新版本的es中,不需要指定not_analyzed也可以,将type=keyword即可。

"articleID": {
   "type": "text",
    "fields": {
      "keyword": {
        "type": "keyword",
        "ignore_above": 256
     }
    }
  },


查看分词

查看下Dynamic mapping下,text类型的分词

field

GET /forum/_analyze
{
  "field": "articleID",
  "text": "XHDK-A-1293-#fJ3"
}

20190512110616391.png


可以看到 articleID建立索引的时候,XHDK-A-1293-#fJ3被分词成了 xhdk,a,1293,fj3


默认是analyzed的text类型的field,建立倒排索引的时候,就会对所有的articleID分词,分词以后,原本的articleID就没有了,只有分词后的各个word存在于倒排索引中。所以根据XHDK-A-1293-#fJ3 去查询,肯定是在 xhdk,a,1293,fj3 中查找不到数据的。


field.keyword

GET /forum/_analyze
{
  "field": "articleID.keyword",
  "text": "XHDK-A-1293-#fJ3"
} 


20190512110631263.png


term,是不对搜索文本分词的,直接将输入的内容去倒排索引中匹配,XHDK-A-1293-#fJ3 --> XHDK-A-1293-#fJ3;但是articleID建立索引的时候,XHDK-A-1293-#fJ3 --> xhdk,a,1293,fj3 ,所以使用 articleID是查不到的, articleID.keyword 是可以查到的。 如下所示


20190512111723955.png


20190512111853354.png


几个小例子


term filter/query:对搜索文本不分词,直接拿去倒排索引中匹配,你输入的是什么,就去匹配什么。 比如说,如果对搜索文本进行分词的话,“helle world” --> “hello”和“world”,两个词分别去倒排索引中匹配 。 term,“hello world” --> “hello world”,直接去倒排索引中匹配“hello world”


这里我们不关心相关度即_score,仅仅是希望通过filter过滤出来数据,所以 使用了 constant_score , 设置相关度都是1.


先通过head插件看下数据


20190512115742320.png


根据用户ID搜索帖子


GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "userID": 1
        }
      }
    }
  }
}


20190512121250148.png


Term Query的写法(推荐)

GET /forum/article/_search
{
  "query": {
    "term": {
      "userID": "1"
    }
  }
}


搜索没有隐藏的帖子

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "hidden": false
        }
      }
    }
  }
}


20190512121336145.png


Term Query的写法(推荐)

{
  "query": {
    "term": {
      "hidden": false
    }
  }
}


根据发帖日期搜索帖子

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "postDate": "2017-01-02"
        }
      }
    }
  }
}


20190512121403637.png


Term Query的写法(推荐)

GET /forum/article/_search
{
  "query": {
    "term": {
      "postDate": "2017-01-02"
    }
  }
}


根据帖子ID搜索帖子

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "articleID": "QQPX-R-3956-#aD8"
        }
      }
    }
  }
}



20190512121417502.png

Term Query的写法(推荐)

GET /forum/article/_search
{
  "query": {
    "term": {
      "articleID": "QQPX-R-3956-#aD8"
    }
  }
}


删除索引,指定articleID的类型


这种Dynamic mapping的情况,肯定是查找不到数据了,要么指定 articleID.keyword。 更推荐自己设置类型,设置成 not_analyzed,或者直接将articleID设置为keyword更加方便。


那我们按照自己设置字段类型keyword的方式来演示下吧


先删掉原来的forum索引

DELETE /forum


手动设置 articleID的类型为 keyword

PUT /forum
{
  "mappings":{
    "article":{
      "properties":{
        "articleID":{
          "type":"keyword"
        }
      }
    }
  }
}


这样的话,就建好了一个 只有一个字段的type. 字段类型确定后无法修改,因为涉及到底层lucene的全文检索。 但是可以增加字段,通过如下的方式,_bulk写入数据的时候,新增几个字段,因为没有指定字段类型,所以是Dynamic Mapping的方式创建的


POST /forum/article/_bulk
{ "index": { "_id": 1 }}
{ "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 2 }}
{ "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" }
{ "index": { "_id": 3 }}
{ "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 4 }}
{ "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }

看下 field的类型

GET /forum/_mapping/article

20190512122401264.png


再次查询下 ,指定articleID的类型为keyword,查询到了数据。


20190512122518406.png



总结一下 term


(1)term filter:根据exact value进行搜索,数字、boolean、date天然支持

(2)text类型的字段需要建索引时指定为not_analyzed或者设置为keyword,才能用term query

(3)term 相当于SQL中的单个where条件

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
数据采集 人工智能 运维
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
本文介绍了阿里云 Elasticsearch 推出的创新型 AI 搜索方案
205 3
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
|
1月前
|
人工智能 自然语言处理 搜索推荐
云端问道12期实操教学-构建基于Elasticsearch的企业级AI搜索应用
本文介绍了构建基于Elasticsearch的企业级AI搜索应用,涵盖了从传统关键词匹配到对话式问答的搜索形态演变。阿里云的AI搜索产品依托自研和开源(如Elasticsearch)引擎,提供高性能检索服务,支持千亿级数据毫秒响应。文章重点描述了AI搜索的三个核心关键点:精准结果、语义理解、高性能引擎,并展示了架构升级和典型应用场景,包括智能问答、电商导购、多模态图书及商品搜索等。通过实验部分,详细演示了如何使用阿里云ES搭建AI语义搜索Demo,涵盖模型创建、Pipeline配置、数据写入与检索测试等步骤,同时介绍了相关的计费模式。
|
1月前
|
人工智能 算法 API
构建基于 Elasticsearch 的企业级 AI 搜索应用
本文介绍了基于Elasticsearch构建企业级AI搜索应用的方案,重点讲解了RAG(检索增强生成)架构的实现。通过阿里云上的Elasticsearch AI搜索平台,简化了知识库文档抽取、文本切片等复杂流程,并结合稠密和稀疏向量的混合搜索技术,提升了召回和排序的准确性。此外,还探讨了Elastic的向量数据库优化措施及推理API的应用,展示了如何在云端高效实现精准的搜索与推理服务。未来将拓展至多模态数据和知识图谱,进一步提升RAG效果。
|
2月前
|
机器学习/深度学习 人工智能 运维
阿里云技术公开课直播预告:基于阿里云 Elasticsearch 构建 AI 搜索和可观测 Chatbot
阿里云技术公开课预告:Elastic和阿里云搜索技术专家将深入解读阿里云Elasticsearch Enterprise版的AI功能及其在实际应用。
171 2
阿里云技术公开课直播预告:基于阿里云 Elasticsearch 构建 AI 搜索和可观测 Chatbot
|
1月前
|
数据采集 人工智能 运维
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
本文介绍了阿里云 Elasticsearch 推出的创新型 AI 搜索方案。
210 5
|
2月前
|
存储 人工智能 API
(Elasticsearch)使用阿里云 infererence API 及 semantic text 进行向量搜索
本文展示了如何使用阿里云 infererence API 及 semantic text 进行向量搜索。
119 8
|
2月前
|
搜索推荐 API 定位技术
一文看懂Elasticsearch的技术架构:高效、精准的搜索神器
Elasticsearch 是一个基于 Lucene 的开源搜索引擎,以其强大的全文本搜索功能和快速的倒排索引技术著称。它不仅支持数字、文本、地理位置等多类型数据,还提供了可调相关度分数、高级查询 DSL 等功能。Elasticsearch 的核心技术流程包括数据导入、解析、索引化、查询处理、得分计算及结果返回,确保高效处理大规模数据并提供准确的搜索结果。通过 RESTful API、Logstash 和 Filebeat 等工具,Elasticsearch 可以从多种数据源中导入和解析数据,支持复杂的查询需求。
178 0
|
3月前
|
存储 缓存 固态存储
Elasticsearch高性能搜索
【11月更文挑战第1天】
75 6
|
3月前
|
API 索引
Elasticsearch实时搜索
【11月更文挑战第2天】
71 1
|
4月前
|
人工智能
云端问道12期-构建基于Elasticsearch的企业级AI搜索应用陪跑班获奖名单公布啦!
云端问道12期-构建基于Elasticsearch的企业级AI搜索应用陪跑班获奖名单公布啦!
193 2

热门文章

最新文章