bodybuild 分为4个部分
- aggregation-builder
- filter-builder
- query-builder
- suggestion-builder
index
通过 build 函数即可生成我们常用的es查询DSL
jsx
build: function build(version) {
var queries = this.getQuery();
var filters = this.getFilter();
var aggregations = this.getAggregations();
var suggestions = this.getSuggestions();
if (version === 'v1') return _buildV1(body, queries, filters, aggregations);
return _build(body, queries, filters, aggregations, suggestions);
}
从上述代码可以看出, bodybuild 通过获取其四大件即可 build 出一个关于ES查询的DSL脚本
入口文件还提供了以下函数
- sort 在给定字段上设置排序方向。
- from 设置from偏移量值,用于对查询进行分页。
- size 设置size值以返回最大结果。
- rawOption 在 elasticsearch 主体上设置任意键值。
- clone 返回bodybuilder的克隆实例
jsx
bodybuilder()
.andFilter('term', 'user', 'kimchy')
.from(2)
.size(3)
.sort('timestamp', 'desc')
{
"from": 2,
"size": 3,
"sort": [
{
"timestamp": {
"order": "desc"
}
}
],
"query": {
"bool": {
"filter": {
"term": {
"user": "kimchy"
}
}
}
}
}
query
dart
/**
* Add a query clause to the query body.
*
* @param {string} type 查询类型。
* @param {string|Object} field 字段来查询或完成查询子句。
* @param {string|Object} value 查询项或内部子句
* @param {Object} options (可选)查询子句的附加选项。
* @param {Function} [nest] (可选)用于将子过滤器定义为子过滤器的函数。这必须是最后一个参数。
*
* @return {bodybuilder} Builder.
*/
- type 第一个参数为请求类型
- field 需要查询的字段
- value 匹配的值
jsx
bodybuilder().query('**match_all**').build()
{
"query": {
"**match_all**": {
}
}
}
jsx
bodybuilder().query('**match_all**', { boost: 1.2 }).build())
{
"query": {
"**match_all**": {
"boost": 1.2
}
}
}
jsx
bodybuilder().query('**match**', 'message', 'this is a test').build())
{
"query": {
"**match**": {
"message": "this is a test"
}
}
}
jsx
bodybuilder().query('**terms**', 'user', ['kimchy', 'elastic']).build())
{
"query": {
"**terms**": {
"user": [
"kimchy",
"elastic"
]
}
}
}
上述三个查询 type 、field、value
结合即可完成简单的搜索查询
options 和 nest
jsx
bodybuilder()
.query(
'nested',
{ path: 'obj1', score_mode: 'avg' },
(q) => {
return q.query('match', 'obj1.name', 'blue')
.query('range', 'obj1.count', { gt: 5 })
})
.build()
// # ES DSL
{
"query": {
"nested": {
"path": "obj1",
"score_mode": "avg",
"query": {
"bool": {
"must": [
{
"match": {
"obj1.name": "blue"
}
},
{
"range": {
"obj1.count": {
"gt": 5
}
}
}
]
}
}
}
}
}
aggregation
dart
/**
* 向查询主体添加聚合子句。
*
* @param {string|Object} type 聚合类型的名称,如"sum"或"terms"。
* @param {string} field 要聚合的字段的名称。
* @param {Object} [options] (可选)要包含在聚合中的其他选项。
* [options._meta] 将元数据与单个聚合关联起来
* [options._name ] 另一种将自定义名称传递给聚合的方法。
* @param {string} [name] (可选) 聚合的自定义名称,默认为 `agg_<type>_<field>`.
* @param {Function} [nest] (可选) 用于将子聚合定义为子聚合的函数。这必须是最后一个参数。
*
* @return {bodybuilder} Builder.
*
*/
这种格式为聚合语句
下面case为type 和 filed的使用
jsx
bodybuilder().aggregation('max', 'price').build()
{
"aggs":{
"agg_max_price":{
"max":{
"field":"price"
}
}
}
}
要包含在聚合中的其他选项。
jsx
bodybuilder()
.aggregation('max', 'price', { percents: [95, 99, 98] })
.build()
{
"aggs": {
"agg_max_price": {
"max": {
"field": "price",
"percents": [
95,
99,
98
]
}
}
}
}
jsx
bodybuilder()
.aggregation('max', 'price', {
format: 'MM-yyy',
ranges: [{ to: 'new-10M/M' }, { from: 'now-10M/M' }]
})
.build()
// # es
{
"aggs": {
"agg_max_price": {
"max": {
"field": "price",
"format": "MM-yyy",
"ranges": [
{
"to": "new-10M/M"
},
{
"from": "now-10M/M"
}
]
}
}
}
}
嵌套aggs
在已经聚合的数据嵌套聚合查询
jsx
bodybuilder()
.aggregation(
'max',
'price',
{
format: 'MM-yyy',
ranges: [{ to: 'new-10M/M' }, { from: 'now-10M/M' }]
},
(a) => {
return a.aggregation('paths', 'text', 'keywords')
}
)
.build()
{
"aggs": {
"agg_max_price": {
"max": {
"field": "price",
"format": "MM-yyy",
"ranges": [
{
"to": "new-10M/M"
},
{
"from": "now-10M/M"
}
]
},
"aggs": {
"keywords": {
"paths": {
"field": "text"
}
}
}
}
}
}
聚合的自定义名称,默认为 agg_<type>_<field>
.
jsx
bodybuilder()
.aggregation(
'max',
'price',
{
_meta: { color: 'blue' }
},
'titles'
)
.build()
{
"aggs": {
"titles": {
"max": {
"field": "price"
},
"meta": {
"color": "blue"
}
}
}
}
filter-builder
jsx
/**
* 向查询主体添加筛选子句。
*
* @param {string} type 过滤器类型。
* @param {string|Object} field 字段或完成过滤子句。
* @param {string|Object} value 过滤项或内部子句。
* @param {Object} options (可选)过滤器子句的附加选项。
* @param {Function} [nest] (可选)用于将子过滤器定义为子过滤器的函数。这必须是最后一个参数。
* @return {bodybuilder} Builder.
*
*/
filter-builder包含几个常规函数分别对应 filter
, andFilter
, addFilter
, orFilter
, notFilter
这些函数和 filter
传参一致,notFilter
和 orFilter
比较特殊
must_not 对应 notFilter
should 对应 orFilter
过滤一个简单参数
dart
# bodybuilder().filter('term', 'user', 'kimchy').build())
{
"query": {
"bool": {
"filter": {
"term": {
"user": "kimchy"
}
}
}
}
}
# bodybuilder().**orFilter**('term', 'user', 'kimchy').build())
{
"query": {
"bool": {
"filter": {
**"bool": {
"should": [
{
"term": {
"user": "kimchy"
}
}
]
}**
}
}
}
}
# bodybuilder().**notFilter**('term', 'user', 'kimchy').build())
{
"query": {
"bool": {
"filter": {
**"bool": {
"must_not": [
{
"term": {
"user": "kimchy"
}
}
]
}**
}
}
}
}
定义子过滤器
dart
filter('nested', { path: 'obj1', mode: 'avg' }, (f) => {
return f.filter('math', 'obj1.name', 'yellow')
})
{
"query": {
"bool": {
"filter": {
"nested": {
"path": "obj1",
"mode": "avg",
"filter": {
"math": {
"obj1.name": "yellow"
}
}
}
}
}
}
}
filter('nested', { path: 'obj1', mode: 'avg' }, (f) => {
return f.filter('math', 'obj1.name', 'yellow')
.filter('range', 'obj1.count', { gt: 5 })
})
{
"query": {
"bool": {
"filter": {
"nested": {
"path": "obj1",
"mode": "avg",
"filter": {
"bool": {
"must": [
{
"math": {
"obj1.name": "yellow"
}
},
{
"range": {
"obj1.count": {
"gt": 5
}
}
}
]
}
}
}
}
}
}
}