搜索引擎elasticsearch常用指令演示
Load ES 接口
http://business-search.aurayou/api/loadES/product/all
交互方式
操作ES有3种方式:
- kibana控制台(Dev Tools)
- Http + json
- api接口
ES支持以下命令:
- GET:获取请求对象的当前状态。
- POST:改变对象的当前状态。
- PUT:创建一个对象。
- DELETE:销毁对象。
- HEAD:请求获取对象的基础信息。
所有操作的格式都类似于:命令 + /索引/类型/ID/ + 操作 + ?选项 + body
比如下面的kibana控制台请求表示:
指令GET,索引aurajike,类型productinfo,ID为空。
操作是_search,选项为_source=id,即只返回id字段
BODY则是筛选的字段条件。
GET aurajike/productinfo/_search?_source=id
{
"query": {
"match": {
"basicInfo.masterName": "蛋糕"
}
}
}
如果是HTTP方式,则对应于HTTP的GET/POST等方法,索引前面补上es的ip:port,如http://192.168.1.212:9200/aurajike/productinfo/_search?_source=id。
api接口的方式则视不同的api参数要求定。
下面我们提供一些kibana控制台的常用操作示例,其他方式可参考修改。
常用操作示例
创建索引
创建文档时,如果索引不存在,es会自动检测文档的字段类型并创建索引。
但默认索引对数组的搜索不友好,所以我们手动创建索引并指定数组为nested
- es默认将数组元素的相同字段的值索引在一起,如{"field1":[v1,v2,v3], "field2":[v4,v5,v6]},这就打乱了原本V1-V4、V2-V5、V3-V6的对应关系。
- 如果要保持数组元素内的字段关系,应指定nested类型,该类型下es会将每个数组的元素存储在一个独立的隐藏文档内,保持元素的内部结构
下面的索引配置指令,我们指定了分片数量1,副本1,分词器ik,mappings字段则指定了文档各个字段的type,重点是数组我们指定为nested。
DELETE aurajike
PUT aurajike
{
"settings":{
"number_of_shards": "1",
"number_of_replicas": "1",
"analysis":{
"analyzer":{
"ik":{
"tokenizer":"ik_smart"
}
}
}
},
"mappings": {
"productinfo": {
"properties": {
"attrList": {
"type": "nested",
"properties": {
"attrId": {
"type": "long"
},
"attrValue": {
"type": "keyword",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "long"
}
}
},
"basicInfo": {
"properties": {
"autoDelivery": {
"type": "long"
},
"defaultSkuId": {
"type": "long"
},
"deliveryType": {
"type": "long"
},
"displaySalesCount": {
"type": "long"
},
"id": {
"type": "long"
},
"masterName": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"maxPrice": {
"type": "long"
},
"minPrice": {
"type": "long"
},
"natureCategoryId": {
"type": "long"
},
"productSource": {
"type": "long"
},
"productStatus": {
"type": "long"
},
"productType": {
"type": "long"
},
"refundAmountType": {
"type": "long"
},
"slave_name": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"sortNumber": {
"type": "long"
},
"sortSalesCount": {
"type": "long"
},
"status": {
"type": "long"
},
"storeType": {
"type": "long"
},
"supplierId": {
"type": "long"
},
"virtualProduct": {
"type": "long"
}
}
},
"categoryId": {
"type": "long"
},
"frontCategoryIdList": {
"type": "long"
},
"salesChannelList": {
"type": "nested",
"properties": {
"availableInventory": {
"type": "long"
},
"displaySalesCount": {
"type": "long"
},
"id": {
"type": "long"
},
"initSalesCount": {
"type": "long"
},
"inventory": {
"type": "long"
},
"price": {
"type": "long"
},
"salesChannelId": {
"type": "long"
},
"salesCount": {
"type": "long"
},
"skuId": {
"type": "long"
},
"slavePrice": {
"type": "long"
}
}
},
"skuList": {
"type": "nested",
"properties": {
"id": {
"type": "long"
},
"marketPrice": {
"type": "long"
},
"masterName": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"price": {
"type": "long"
},
"slaveCostPrice": {
"type": "long"
},
"slaveName": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"skuOptionList": {
"type": "nested",
"properties": {
"id": {
"type": "long"
},
"option_id": {
"type": "long"
},
"option_value": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"skuId": {
"type": "long"
}
}
}
}
}
}
}
添加文档
用post方法可以由es为我们自动生成一串由英文字母或数字组成的20字节唯一的ID。
对于商品的文档,建议就以商品ID为文档ID,即PUT /aurajike/productinfo/[productID],从而在已知ID的情况下可以直接获取到商品详情。否则,得拿ID去搜索。
get aurajike/productinfo/_search
# 指定id
PUT /aurajike/productinfo/1
{
"basicInfo": {
"productId": 1,
"masterName": "四季芝士蛋糕(四拼)",
"slaveName": "草莓 蓝莓 芝士 巧克力 如四季流转各具风味"
},
"categoryId": 105,
}
// 由es自动生成id
POST /aurajike/productinfo
{
"basicInfo": {
"productId": 1,
"masterName": "自动ID示例",
"slaveName": "自动ID示例"
},
"categoryId": 105
}
删除文档
DELETE /aurajike/productinfo/1
修改文档
修改文档可以有以下几种方式:
- PUT: 指定ID添加一个新文档,将旧文档直接覆盖掉
- POST + _update 更新或插入字段
- 执行脚本:能够比前两种方式更灵活且强大
对于数据库增量更新,POST + _update 感觉比较好用。
# 文档覆盖,旧文档将删除,新文档只有这里插入的categoryId字段
PUT /aurajike/productinfo/1
{
"categoryId": 505
}
# 更新和插入字段
# basicInfo.basicInfo.slaveName:这个字段在原文档已存在,所以是更新
# newField:这个字段原文档不存在,所以会新增
POST /aurajike/productinfo/1/_update
{
"doc": {
"basicInfo" : {
"slaveName" : "更新这个字段"
},
"newField": "新增这个字段"
}
}
# 执行脚本:更新字段
# ctx._source代表当前的文档,后面可以直接跟文档的字段
# 这条指令我们把basicInfo的categoryId字段在原值基础上加了101
POST /aurajike/productinfo/1/_update
{
"script" : "ctx._source.categoryId += 101"
}
# 执行脚本:数组元素的增删改
# 假设我们的文档里有如下结构:
# {
# "attrList": [
# {
# "id": 20223,
# "attrId": "1001",
# "attrValue": "满99元包邮"
# },
# {
# "id": 20232,
# "attrId": "1001",
# "attrValue": "7天无理由退换货"
# }
# ]
# }
# 下面的语句先删除(removeIf) id==20223 && attrId=="1001"的数组元素
# 然后添加attr字段内容到数组内。
POST /aurajike/productinfo/1/_update
{
"script": {
"source": "ctx._source.attrList.removeIf(item -> (item.id==20223 && item.attrId==\"1001\"));ctx._source.user.add(params.attr)",
"params": {
"attr": {
"id": 20223,
"attrId": "1002",
"attrValue": "江浙沪包邮"
}
}
}
}
查询
简单查询
ES内置字段含义:
_source: 在get和_mget等命令里,_source 表示需要检索的字段,请求和响应的body里均包含此字段
found: 响应帧需要判断每个body前面的found字段,found == true时body字段才有效,否则未查找到结果
下面的示例包含获取指定文档、条件查询、指定返回的字段、分页、排序、批量查询等。
# 获取指定文档
GET /aurajike/productinfo/1/
# 搜索"masterName"字段包含"蛋糕"关键字的文档
# 只返回两个字段:_source=categoryId,basicInfo.productId
# 按categoryId降序
GET aurajike/_search?_source=categoryId,basicInfo.productId
{
"query": { # 查询条件
"match": {
"basicInfo.masterName": "蛋糕"
}
},
"from":0,"size":20, # 分页
"sort": { "categoryId": { "order": "desc" }} # 排序
}
# 多文档查询_mget
# 方式一:GET /_mget,不同的_index、_type等字段在body内指定
# 方式二:GET /aurajike/productinfo,索引和类型相同,body指定id或不指定
# 下面这条搜索语句返回/aurajike/productinfo/下的所有文档的productId字段,以及/index/type/1/文档的test字段
GET /_mget
{
"docs" : [
{"_index":"aurajike","_type":"productinfo","_id":1,
"_source": "basicInfo.productId"
},
{"_index":"index","_type":"type","_id":1,"_source":"test"}
]
}
# 获取1~5这5个文档
GET /aurajike/productinfo/_mget
{
"ids" : [ "1", "2", "3", "4", "5" ]
}
高级多条件查询
现实中的查询操作往往的多条件复杂的查询,这类查询,es也是支持的。
es支持的组合查询参数有4类:
- must: 文档 必须 匹配这些条件才能被包含进来。
- must_not: 文档 必须不 匹配这些条件才能被包含进来。
- should:
- 当存在must或must_not语句时:should语句可以用来加分。即满足should语句的文档在排序上有加分,满足的越多加分越多。一条都不满足时对匹配结果无影响
- 当没有must或must_not语句时:至少要匹配一条should语句
- filter: 必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。
上面提到的加分,是指在bool查询时es会计算文档在匹配条件上的相关性得分,得分高的排序优先。
所以如果不需要对相关性进行计算,应直接用filter参数,可以提高性能。
filter过滤器的性能远大于评分查询,所以不需要相关性评分的情况应都用filter:一方面评分计算耗时,而filter是不评分的;另一方面filter会被缓存
引用官方的话:通常的规则是,使用 查询(query)语句来进行 全文 搜索或者其它任何需要影响 相关性得分 的搜索。除此以外的情况都使用过滤(filters)。
现在我们来演示一组复杂的组合查询:
GET /aurajike/productinfo/_search
{
"_source": "_id", # 只返回文档ID(文档ID = 商品ID)
"from": 0,"size": 10, # 分页
"sort": {"basicInfo.maxPrice": {"order": "desc"}}, # 按最大价格降序
"query": {
"bool": {
"filter": [ # filter过滤,不计算相关性;1/2/3/4/5/6语句是 与 的关系
{"terms": {"frontCategoryIdList": [145,277]}}, # 1. 筛选前端类目ID为145或者277的商品
{ # 2.筛选配送地区包含上海310100的商品
"bool": {
"should": [ # 2.1 / 2.2 两条语句是 或 的关系,满足其一即语句2为真
{
"bool": { # 2.1 属性ID为19的是配送范围,不存在ID为19的属性即表示全国配送
"must_not": {
"nested": { # attrList是数组nested格式,必须用nested方式才能搜索到
"path": "attrList",
"query": {
"bool": {
"must": [
{
"term": {
"attrList.attrId": 19
}
}
]
}
}
}
}
}
},
{
"nested": { # 2.2 或者配置范围是上海的
"path": "attrList",
"query": {
"bool": {
"must": [
{
"term": {
"attrList.attrId": 19
}
},
{
"terms": {
"attrList.attrValue": [
"","310000","310101","310114","310105",
"310109","310112","310113","310118",
"310120","310151","310106","310110",
"310115","310116","310117","310100",
"310104","310107"
]
}
}
]
}
}
}
}
]
}
}
{ # 3. 属性筛选
"nested": {
"path": "attrList",
"query": {
"bool": {
"must": [
{"term": {"attrList.attrId": 22}},
{"terms": {"attrList.attrValue": ["40"]}}
]
}
}
}
},
{ # 4. 属性筛选
"nested": {
"path": "attrList",
"query": {
"bool": {
"must": [
{"term": {"attrList.attrId": 27}},
{"terms": {"attrList.attrValue": ["3"]}}
]
}
}
}
},
{ # 5. 商品或SKU名称关键字匹配
"bool": {
"should": [
{"match": {"basicInfo.masterName": "枇杷"}},
{"match": {"basicInfo.slave_name": "枇杷"}},
{"match": {"skuList.masterName": "枇杷"}},
{"match": {"skuList.slaveName": "枇杷"}}
]
}
},
{ # 6. 属性过滤
"bool": {
"must_not": {
"nested": {
"path": "attrList",
"query": {
"bool": {
"must": [
{"term": {"attrList.attrId": 1006}},
{"term": {"attrList.attrValue": "1"}}
]
}
}
}
}
}
}
]
}
}
}
搜索引擎elasticsearch常用指令演示的更多相关文章
- 搜索引擎elasticsearch + kibana + X-pack + IK安装部署
目录 准备安装环境 配置启动 启动elasticsearch 启动kibana 启用X-pack 安装使用IK 使用示例 官方Clients 准备安装环境 这次我们安装以下软件或插件: elastic ...
- 基于header的一些常用指令详解
header常用指令 header分为三部分: 第一部分为HTTP协议的版本(HTTP-Version): 第二部分为状态代码(Status): 第三部分为原因短语(Reason-Phrase) ...
- shell分析日志常用指令合集
数据分析对于网站运营人员是个非常重要的技能,日志分析是其中的一个.日志分析可以用专门的工具进行分析,也可以用原生的shell脚本执行,下面就随ytkah看看shell分析日志常用指令有哪些吧.(log ...
- sql*plus常用指令介紹
sql*plus常用指令介紹 1.用set指令來設定SQL*Plus的環境參數值 格式: Set 環境參數名 環境參數值 ex:set feedback on set feedback 8.用show ...
- Vue - vue.js 常用指令
Vue - vue.js 常用指令 目录: 一. vuejs模板语法之常用指令 1. 常用指令: v-html 2. 常用指令: v-text 3. 常用指令: v-for 4. 常用指令: v-if ...
- vue 的基本语法和常用指令
什么是vue.js Vue.js是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站,还可以开发手机App, Vue语法也是可以用于进行手机App开发的,需要借助于Wee ...
- 【Vue常用指令】
目录 v-html v-text v-for v-if v-show v-bind v-on v-model 指令修饰符 计算与侦听属性 自定义属性 获取DOM元素 "@ *** Vue.j ...
- Vue专题-js常用指令
vue.js官方给自己的定为是数据模板引擎,并给出了一套渲染数据的指令.本文详细介绍了vue.js的常用指令. vue.js常用指令 Vue.js使用方式及文本插值 Vue.js 使用了基于 HTML ...
- 搜索引擎ElasticSearch入门
前言 最近项目上需要用到搜索引擎,由于之前自己没有了解过,所以整理了一下搜索引擎的相关概念知识. 正文 想查数据就免不了搜索,搜索就离不开搜索引擎,百度.谷歌都是一个非常庞大复杂的搜索引擎,他们几乎索 ...
随机推荐
- Jenkins+Gitlab+Ansible自动化部署(三)
接Jenkins+Gitlab+Ansible自动化部署(一)https://www.cnblogs.com/zd520pyx1314/p/10210727.html 和(二)https://www. ...
- Spark Mllib里如何程序输出数据集的条数(图文详解)
不多说,直接上干货! 具体,见 Hadoop+Spark大数据巨量分析与机器学习整合开发实战的第17章 决策树多元分类UCI Covertype数据集
- 【转载】【MVC 学习 Razor语法】
Razor是MVC3中才有的新的视图引擎.我们知道,在ASP.NET中,ASPX的视图引擎依靠<%和%>来调用C#指令.而MVC3以后有了一套新的使用@标记的Razor语法,使用起来更灵活 ...
- 关于dataTable 生成JSON 树
背景: POSTGRESL + C# + DHTMLX SUIT 一个表生成一个JSON串,这个不是很麻烦: 1.在数据库(postges)中: json_agg(row_to_json(t)) ...
- ecshop分类页把分类描述改成FCKeditor编辑器
最近放一个网站 http://www.macklin.cn/productline/35 有个产品分类页面需要添加分类缩略图和图文的描述 一.首先说下添加分类缩略图的步骤吧 1,依葫芦画瓢,参照的是e ...
- cocos2d-x入门学习篇;切换场景
手机游戏开发最近很火爆,鉴于一直在学习c++,看起来上手就比较快了.这篇文章来自皂荚花 cocos2d-x技术,我把我的想法分享给大家. 首先来看一段代码: CCScene* HelloWorld:: ...
- 有一个无效 SelectedValue,因为它不在项目列表中
“Drp_XX”有一个无效 SelectedValue,因为它不在项目列表中 出现以上异常的原因肯定是将DrowDownList控件的SelectedValue属性赋值为一个列表中不存在的值.那么我们 ...
- ThinkPHP笔记——开启debug调试模式
debug+trace模式可以查看开发过程中TP的错误信息,可以更好地帮助开发者debug.但是debug模式的开启还不是简单的在配置文件中中设置就可以的,经过查资料摸索,找到一种有效的方法. 首先在 ...
- [dp]uestc oj E - 菲波拉契数制
E - 菲波拉契数制 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- HDU 4284 Travel (Folyd预处理+dfs暴搜)
题意:给你一些N个点,M条边,走每条边要花费金钱,然后给出其中必须访问的点,在这些点可以打工,但是需要先拿到证书,只可以打一次,也可以选择不打工之直接经过它.一个人从1号点出发,给出初始金钱,问你能不 ...