1、检索、排序
terms表示查询的内容只要满足任意一个都被搜索出来
sort节点指定排序字段
<pre>
{
"query": {
"terms": {
"content": [
"二季度",
"租房",
"上海"
]
}
},
"sort": {
"ttl": {
"order": "desc"
}
}
}
</pre>
2、//should指的是满足任意一个条件,must指的是满足全部条件或must_no 排除 这个条件
<pre>
{
"query": {
"bool": {
"must": [
{ "match": { "content": "上海" } },
{ "match": { "url": "baidu" } },
{ "match": { "ch": 7 } }
]
}
}
}
</pre>
3、全匹配 ,整个短语进行匹配
<pre>
{
"query": {
"match_phrase": {
"content": "发生在上海"
}
}
}
</pre>
4、模糊查询 ,query的内容会自动进行分词拆分
<pre>
{
"query": {
"query_string": {
"default_field": "content",
"query": "上海美国"
}
}
}
</pre>
5、邻近,短语之间不超过多少个词
<pre>
{"query": {
"match_phrase": {
"title": {
"query": "quick fox",
"slop": 15
}
}
}
}
</pre>
content包含“反正”和“避让”,间隔不超10词
<pre>
{
"query": {
"match_phrase": {
"content": {
"query": "反正 避让",
"slop": 10
}
}
}
}
</pre>
6、having 聚合
context包含“今年”,按url聚合,聚合数>1,order by聚合数,时间范围15/7/9-16/1/7
<pre>
{
"query" : {
"bool": {
"must":[
{"match": { "content" : "今年" }},
{
"query": {"range" : {
"ttl" : {
"gt" : "2015-07-09",
"lt" : "2016-01-07"
}
}}
}
]
}
},
"aggs": {
"url": {
"terms": {
"field": "url",
"size": 0,
"order" : { "_count" : "asc"}
},
"aggs": {
"having": {
"bucket_selector": {
"buckets_path": {
"url_count": "_count"
},
"script": {
"lang": "expression",
"inline": " url_count > 1"
}
}
}
}
}
},
"size": 0
}
</pre>
再增加一个having的示范,对于得sql语句为:
<pre>
SELECT ipo_year, COUNT(*) AS ipo_count FROM symbol
GROUP BY ipo_year HAVING ipo_count > 200
</pre>
DSL的语法为:
<pre>
{
"aggs": {
"ipo_year": {
"terms": {
"field": "ipo_year",
"size": 0
},
"aggs": {
"having": {
"bucket_selector": {
"buckets_path": {
"ipo_count": "_count"
},
"script": {
"lang": "expression",
"inline": " ipo_count > 200"
}
}
}
}
}
},
"size": 0
}
</pre>
7、content包含租房,上海加权因子10,南京加权因子1
<pre>
{
"query": {
"bool": {
"must": {
"match": {
"content": {
"query": "租房",
"operator": "and"
}
}
},
"should": [
{ "match": { "content": {"query": "上海",
"boost": 10 }}},
{ "match": { "content": {"query": "南京",
"boost": 1} }}
]
}
}}
</pre>
8、组合filter
content:"上海","ch": 7,"url" :sina或者baidu
"size": 1表示为仅显示1条结果,通过filter可以组成很复杂的查询条件组合
<pre>
{
"query": {
"bool": {
"filter": [
{
"term": {
"content": "上海"
}
},
{
"term": {
"ch": 7
}
}
,
{
"terms": {
"url" : ["sina.com","baidu.com"]
}
}
]
}
},
"size": 1
}
</pre>
9、join查询,需要安装siren-join插件满足
<pre>
{
"coordinate_search": {
"actions": [
{
"relations": {
"from": {
"indices": ["index2"],
"types": ["text2"],
"field": "ch"
},
"to": {
"indices": ["index"],
"types": ["text"],
"field": "foreign_key"
}
},
"size": 2,
"size_in_bytes": 20,
"is_pruned": false,
"cache_hit": false,
"terms_encoding" : "long",
"took": 313
}
]
}
}
</pre>
关于Elasticsearch如何支持join,这个slide总结得很好:http://www.slideshare.net/sirensolutions/searching-relational-data-with-elasticsearch。总体来说有这么几种方式:
• 完全不join,把关联表的字段融合到一张表里。当然这会造成数据的冗余
• 录入的时候join:使用 nested documents(nested document和主文档是同segment存储的,对于一个symbol,几千万个quote这样的场景就不适合了)
• 录入的时候join:使用 siren
• 查询时join:使用 parent/child (这个是elasticsearch的特性,要求parent/child同shard存在)
• 查询时join:使用 siren-joins(就是一个在服务端求值的filter,然后把结果发布给每个shard去做二次match)
• 查询时join:在客户端拼装第二个查询(和siren-joins差不多,但是多了一次客户端到服务器的来回)
• 查询时join:在coordinate节点上做两个查询的join合并(https://github.com/NLPchina/elasticsearch-sql)
我个人喜欢的是siren-joins和客户端拼装这两种方案。这两种方案都是先做了一次查询,把查询结果再次分发到每个分布式节点上再次去做分布式的聚合。相比在coordinate节点上去做join合并更scalable。
Elasticsearch官方说明如下(就算是不推荐,不要使用2个index就行join):
Joining queriesedit
Performing full SQL-style joins in a distributed system like Elasticsearch is prohibitively expensive. Instead, Elasticsearch offers two forms of join which are designed to scale horizontally.
nested query Documents may contains fields of type nested. These fields are used to index arrays of objects, where each object can be queried (with the nested query) as an independent document. has_child and has_parent queries A parent-child relationship can exist between two document types within a single index. The has_child query returns parent documents whose child documents match the specified query, while the has_parent query returns child documents whose parent document matches the specified query.
Also see the terms-lookup mechanism in the terms query, which allows you to build a terms query from values contained in another document.