Python Elasticsearch DSL 搜索

使用ElasticSearch DSL進行搜索

Search主要包括:

  • 查詢(queries)
  • 過濾器(filters)
  • 聚合(aggreations)
  • 排序(sort)
  • 分頁(pagination)
  • 額外的參數(additional parameters)
  • 相關性(associated)

創建一個查詢對象

<code>from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search
client = Elasticsearch()
s = Search(using=client)/<code>


初始化測試數據

<code># 創建一個查詢語句s = Search().using(client).query("match", title="python")# 查看查詢語句對應的字典結構print(s.to_dict())# {'query': {'match': {'title': 'python'}}}# 發送查詢請求到Elasticsearchresponse = s.execute()# 打印查詢結果for hit in s:    print(hit.title)# Out:Python is good!Python very quickly# 刪除查詢s.delete()/<code>


第一個查詢語句

<code># 創建一個查詢語句
s = Search().using(client).query("match", title="python")
# 查看查詢語句對應的字典結構

print(s.to_dict())
# {'query': {'match': {'title': 'python'}}}
# 發送查詢請求到Elasticsearch
response = s.execute()
# 打印查詢結果
for hit in s:
print(hit.title)
# Out:
Python is good!
Python very quickly
# 刪除查詢
s.delete()/<code>


1、Queries

<code># 創建一個多字段查詢
multi_match = MultiMatch(query='python', fields=['title', 'body'])
s = Search().query(multi_match)
print(s.to_dict())
# {'query': {'multi_match': {'fields': ['title', 'body'], 'query': 'python'}}}
# 使用Q語句
q = Q("multi_match", query='python', fields=['title', 'body'])
# 或者
q = Q({"multi_match": {"query": "python", "fields": ["title", "body"]}})
s = Search().query(q)
print(s.to_dict())
# If you already have a query object, or a dict
# representing one, you can just override the query used
# in the Search object:
s.query = Q('bool', must=[Q('match', title='python'), Q('match', body='best')])
print(s.to_dict())
# 查詢組合
q = Q("match", title='python') | Q("match", title='django')
s = Search().query(q)
print(s.to_dict())
# {"bool": {"should": [...]}}
q = Q("match", title='python') & Q("match", title='django')
s = Search().query(q)
print(s.to_dict())
# {"bool": {"must": [...]}}
q = ~Q("match", title="python")
s = Search().query(q)

print(s.to_dict())
# {"bool": {"must_not": [...]}}/<code>

2、Filters

<code>s = Search()
s = s.filter('terms', tags=['search', 'python'])
print(s.to_dict())
# {'query': {'bool': {'filter': [{'terms': {'tags': ['search', 'python']}}]}}}
s = s.query('bool', filter=[Q('terms', tags=['search', 'python'])])
print(s.to_dict())
# {'query': {'bool': {'filter': [{'terms': {'tags': ['search', 'python']}}]}}}
s = s.exclude('terms', tags=['search', 'python'])
# 或者
s = s.query('bool', filter=[~Q('terms', tags=['search', 'python'])])
print(s.to_dict())
# {'query': {'bool': {'filter': [{'bool': {'must_not': [{'terms': {'tags': ['search', 'python']}}]}}]}}}/<code>

3、Aggregations

<code>s = Search()
a = A('terms', filed='title')
s.aggs.bucket('title_terms', a)
print(s.to_dict())
# {
# 'query': {
# 'match_all': {}
# },
# 'aggs': {
# 'title_terms': {
# 'terms': {'filed': 'title'}
# }
# }
# }
# 或者
s = Search()
s.aggs.bucket('articles_per_day', 'date_histogram', field='publish_date', interval='day') \\
.metric('clicks_per_day', 'sum', field='clicks') \\
.pipeline('moving_click_average', 'moving_avg', buckets_path='clicks_per_day') \\
.bucket('tags_per_day', 'terms', field='tags')
s.to_dict()
# {
# "aggs": {
# "articles_per_day": {
# "date_histogram": { "interval": "day", "field": "publish_date" },
# "aggs": {

# "clicks_per_day": { "sum": { "field": "clicks" } },
# "moving_click_average": { "moving_avg": { "buckets_path": "clicks_per_day" } },
# "tags_per_day": { "terms": { "field": "tags" } }
# }
# }
# }
# }/<code>

4、Sorting

<code>s = Search().sort(
'category',
'-title',
{"lines" : {"order" : "asc", "mode" : "avg"}}
)/<code>

5、Pagination

<code>s = s[10:20]
# {"from": 10, "size": 10}/<code>

6、Extra Properties and parameters

<code>s = Search()
# 設置擴展屬性使用`.extra()`方法
s = s.extra(explain=True)
# 設置參數使用`.params()`
s = s.params(search_type="count")
# 如要要限制返回字段,可以使用`source()`方法
# only return the selected fields
s = s.source(['title', 'body'])
# don't return any fields, just the metadata
s = s.source(False)
# explicitly include/exclude fields
s = s.source(include=["title"], exclude=["user.*"])
# reset the field selection
s = s.source(None)
# 使用dict序列化一個查詢
s = Search.from_dict({"query": {"match": {"title": "python"}}})
# 修改已經存在的查詢

s.update_from_dict({"query": {"match": {"title": "python"}}, "size": 42})/<code>


分享到:


相關文章: