DSL
从索引的某个TEXT字段抽取最重要的TOPN个关键词,如何编写DSL?
Elasticsearch • laoyang360 回复了问题 • 2 人关注 • 1 个回复 • 2462 次浏览 • 2022-12-02 11:20
是否存在Solr query URL到ES query DSL工具?
Elasticsearch • printlove 回复了问题 • 2 人关注 • 1 个回复 • 4405 次浏览 • 2021-12-09 16:30
elasticsearch query与agg分开是否可以提高性能?
Elasticsearch • tongchuan1992 回复了问题 • 2 人关注 • 1 个回复 • 2412 次浏览 • 2021-07-08 09:24
ES client 请求数据报错UnicodeDecodeError
回复Elasticsearch • elasticStack 回复了问题 • 1 人关注 • 1 个回复 • 2149 次浏览 • 2021-03-09 15:29
es7.3怎么生成日期相差天数的字段
Elasticsearch • tacsklet 回复了问题 • 2 人关注 • 1 个回复 • 3584 次浏览 • 2020-03-23 12:00
查询语句无误,但是不显示查询结果的问题
Kibana • sailershen 回复了问题 • 2 人关注 • 3 个回复 • 5265 次浏览 • 2019-07-18 23:02
怎么从kibana生成图表的功能获得es的dsl语句
Kibana • Ombres 回复了问题 • 6 人关注 • 5 个回复 • 5189 次浏览 • 2019-07-16 16:31
kibana查询成转DSL
Elasticsearch • xiaoke 回复了问题 • 5 人关注 • 4 个回复 • 5668 次浏览 • 2019-07-12 11:28
es-scroll迭代问题
Elasticsearch • puyunjiafly 回复了问题 • 5 人关注 • 3 个回复 • 5219 次浏览 • 2019-01-23 15:37
初试es6.5.4的composite出错
Elasticsearch • rochy 回复了问题 • 2 人关注 • 1 个回复 • 3499 次浏览 • 2019-01-17 15:39
请教一个多索引字段比对查询写法的问题
Elasticsearch • rochy 回复了问题 • 4 人关注 • 1 个回复 • 2764 次浏览 • 2019-01-17 10:01
查询效率和mapping的关系
Elasticsearch • elasticStack 回复了问题 • 6 人关注 • 7 个回复 • 4198 次浏览 • 2019-01-11 14:35
es前缀匹配
Elasticsearch • laoyang360 回复了问题 • 3 人关注 • 2 个回复 • 9855 次浏览 • 2019-01-03 12:35
ES使用scripts的来过滤数据
Elasticsearch • LovelyFeng 回复了问题 • 3 人关注 • 2 个回复 • 9146 次浏览 • 2018-10-30 17:36
es如何优化一个慢查询
Elasticsearch • elk123 回复了问题 • 2 人关注 • 1 个回复 • 4932 次浏览 • 2018-10-29 12:46
[code]
POST _bulk
{"index":{"_index":"... 显示全部 »
[code]
POST _bulk
{"index":{"_index":"book","_type":"doc","_id":"1"}}
{"book":"book1","author":["tom","lee","lucy"]}
{"index":{"_index":"book","_type":"doc","_id":"2"}}
{"book":"book2","author":["tom","lee"]}
{"index":{"_index":"book","_type":"doc","_id":"3"}}
{"book":"book3","author":["tom","lee","lili"]}
{"index":{"_index":"book","_type":"doc","_id":"4"}}
{"book":"book4","author":["tom","lili"]}
{"index":{"_index":"book","_type":"doc","_id":"5"}}
{"book":"book5","author": }
GET book/_search
{
"size":0,
"query":{
"term":{
"author":"tom"
}
},
"aggs":{
"co-authors":{
"terms":{
"field": "author.keyword",
"min_doc_count": 2
}
}
}
}
1. 在mapping里指定search_analyzer,例如 PUT my_index
{
"mappings": {
"doc": {
"prope... 显示全部 »
1. 在mapping里指定search_analyzer,例如 PUT my_index
{
"mappings": {
"doc": {
"properties": {
"uid": {
"type": "keyword"
},
"name": {
"type": "text",
"analyzer": "english",
"search_analyzer": "standard"
}
}
}
}
}
2.使用URL Search的时候,指定analyzer参数 ,文档参考: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html , 对应的python代码范例: >>> es.search(index="my_index", analyzer="standard", q='name:"mark AND johnson"') 要注意的是,这里的analyzer只能和q这个参数搭配使用。 你的代码报错,是因为用的body参数,这个参数是没有analyzer参数搭配的。
3.使用Request Body Search,文档参考: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html ,对应的python代码范例: >>> dsl='{"query": {"match": {"name": {"query": "mark","analyzer": "standard"}}}}'
>>> es.search(index="my_index", body=dsl) 注意这个时候,analyzer是写到dsl里面的match query。
从索引的某个TEXT字段抽取最重要的TOPN个关键词,如何编写DSL?
回复Elasticsearch • laoyang360 回复了问题 • 2 人关注 • 1 个回复 • 2462 次浏览 • 2022-12-02 11:20
是否存在Solr query URL到ES query DSL工具?
回复Elasticsearch • printlove 回复了问题 • 2 人关注 • 1 个回复 • 4405 次浏览 • 2021-12-09 16:30
elasticsearch query与agg分开是否可以提高性能?
回复Elasticsearch • tongchuan1992 回复了问题 • 2 人关注 • 1 个回复 • 2412 次浏览 • 2021-07-08 09:24
ES client 请求数据报错UnicodeDecodeError
回复Elasticsearch • elasticStack 回复了问题 • 1 人关注 • 1 个回复 • 2149 次浏览 • 2021-03-09 15:29
Day4: 《将sql转换为es的DSL》
Advent • Xargin 发表了文章 • 6 个评论 • 36163 次浏览 • 2016-12-04 23:23
select * from x_order where userId = 1 order by id desc limit 10,1;
解析之后会变成golang的一个struct,来看看具体的定义:
&sqlparser.Select{
Comments:sqlparser.Comments(nil),
Distinct:"",
SelectExprs:sqlparser.SelectExprs{(*sqlparser.StarExpr)(0xc42000aee0)},
From:sqlparser.TableExprs{(*sqlparser.AliasedTableExpr)(0xc420016930)},
Where:(*sqlparser.Where)(0xc42000afa0),
GroupBy:sqlparser.GroupBy(nil),
Having:(*sqlparser.Where)(nil),
OrderBy:sqlparser.OrderBy{(*sqlparser.Order)(0xc42000af20)},
Limit:(*sqlparser.Limit)(0xc42000af80),
Lock:""
}
sql的select语句在被解析之后生成一个Select的结构体,如果我们不关心使用者需要的字段的话,可以先把SelectExprs/Distinct/Comments/Lock里的内容忽略掉。如果不是分组统计类的需求,也可以先把GroupBy/Having忽略掉。这里我们关心的就剩下From、Where、OrderBy和Limit。
From对应的TableExprs实际上可以认为是简单的字符串,这里的值其实就是`x_order`。
OrderBy实际上是一个元素为type Order struct {
Expr ValExpr
Direction string
}\
的数组。
Limit也很简单,type Limit struct {
Offset, Rowcount ValExpr
}
其实就是俩数字。
那么剩下的就是这个Where结构了。where会被解析为AST(`https://en.wikipedia.org/wiki/Abstract_syntax_tree`),中文是抽象语法树。在不说子查询之类的情况下,这个AST也不会太复杂,毕竟where后面的情况比起编译原理里的程序语言来说情况还是要少得多的。以上述的sql为例,这里解析出来的Where结构是这样的:&sqlparser.Where{
Type:"where",
Expr:(*sqlparser.ComparisonExpr)(0xc420016a50)
}
只有一个节点,一个ComparisonExpr表达式,这个ComparisonExpr,中文比较表达式,指代的就是我们sql里的`user_id = 1`。实际上我们可以认为这个"比较表达式"即是所有复杂AST的叶子节点。叶子结点在AST遍历的时候一般也就是递归的终点。因为这里的查询比较简单,整棵AST只有一个节点,即根节点和叶子节点都是这个ComparisonExpr。
再来一个复杂点的例子。select * from users where user_id = 1 and product_id =2
=>
&sqlparser.Where{
Type:"where",
Expr:(*sqlparser.AndExpr)(0xc42000b020)
}
AndExpr有Left和Right两个成员,分别是:
Left:
&sqlparser.ComparisonExpr{
Operator:"=",
Left:(*sqlparser.ColName)(0xc4200709c0),
Right:sqlparser.NumVal{0x31}
}
Right:
&sqlparser.ComparisonExpr{
Operator:"=",
Left:(*sqlparser.ColName)(0xc420070a50),
Right:sqlparser.NumVal{0x32}
}
稍微有一些二叉树的样子了吧。把这棵简单的树画出来:
回到文章开头的那个复杂的例子:a and (b and (c or d) and e)
=>
select * from user_history where user_id = 1 and (product_id = 2 and (star_num = 4 or star_num = 5) and banned = 1)
看着真够麻烦的,我们把这棵树画出来:
这样看着就直观多了。我们有了AST的结构,那要怎么对应到es的查询DSL呢?少安毋躁。
我们知道es的bool query是可以进行嵌套的,所以实际上我们可以同样可以构造出树形结构的bool query。这里把bool嵌套must和bool嵌套should简化一下,写成boolmust和boolshould:
例如a and (b and c)query {
boolmust {
a,
boolmust {
b,
c
}
}
}
我们把query内部的第一个boolmust当作根节点,内部嵌套的a和另一个boolmust当作它的两个子节点,然后b和c又是这个boolmust的子节点。可以看出来,实际上这棵树和AST的节点可以一一对应。
再回到文章开头的例子,a and (b and (c or d) and e):query {
boolmust {
a,
boolmust {
b,
boolshould {
c,
d
},
e
}
}
}
和前文中ast来做个简单的结构对比~
和前文中sql的where解析后的AST树也是完全匹配的。思路来了,只要对sql解析生成的AST进行递归,即可得到这棵树。当然了,这里还可以进行一些优化,如果子节点的类型和父
节点的类型一致,例如都是and表达式或者都是or表达式,我们可以在生成dsl的时候将其作为并列的节点进行合并,这里不再赘述。
在递归中有这么几种情况:AndExpr => bool must [{left}, {right}]
OrExpr => bool should [{left}, {right}]
ComparisonExpr => 一般是叶子节点
ParenBoolExpr => 指代括号表达式,其实内部是上述三种节点的某一种,所以直接取出内部节点按上述方法来处理
这样问题就变成了如何处理AST的叶子节点。前面提到了叶子节点实际上就是Comparison Expression。只要简单进行一些对应即可,下面是我们的项目里的一些对应关系,仅供参考:
最后再附上demo
https://github.com/cch123/elasticsql