Fork me on GitHub

Learning Elasticsearch (iii)

Searching (first part)

search接口基本用法

search功能是elasticsearch的一个核心功能。通过构造搜索语句,用户可以获取各类目标数据。

search API

Python elasticsearch提供了search函数用以调用search API。其中,查询语句(Query DSL), 以参数body的形式传入(或原生Lucene语句以q参数形式传入)。例如,想要搜索index索引下,type类型中,所有字段a='ban'的文档,可以这样构建搜索参数:

search_body = {
    'query': {
        'match': {
            'a': 'ban',
        },
    },
}
es.search(index='index', doc_type='type', body=search_body)

结果将显示所有包含该字段的文档。
上述搜索结果可以看出如下问题:
1. 结果最多返回了10条
2. a等于banner的结果也返回了

分页查询

对于上述问题1,elasticsearch的search接口默认只返回10条数据。如果你需要更多的数据,可以通过size参数指定,也可以通过from参数指定起始位置以便分页查询:

search_body = {
    'query': {
        'match': {
            'a': 'ban',
        },
    },
    'size': 20,
    'from': 100,
}
es.search(index='index', doc_type='type', body=search_body)

这样将返回低10011920条数据。 事实上,elasticsearch支持更快速的scroll方法来分页查询数据。当你在search中增加scroll参数并指定一个时间时(例如,scroll=1m 1分钟),elasticsearch将自动保存当前的搜索上下文直至生命周期结束。同时,ES将在搜索结果中返回一个scroll_id。当你下一次发起搜索请求时,你可以直接利用scroll_id去访问数据:

search_body = {
    'query': {
        'match': {
            'a': 'ban',
        },
    },
}
res = es.search(index='index', doc_type='type', body=search_body, scroll='1m')
scroll_id = res.get('_scroll_id')
scroll_res = es.scroll(scroll_id=scroll_id, scroll='2m')#Set another scroll expiry time

注:每次调用scroll函数都将返回新的scroll_id,并刷新过期时间(或再次指定过期时间)

你可以通过clear_scroll接口手动删除某些scroll

es.clear_scroll(scroll_id=scroll_id)

限制返回字段

希望限制search接口返回的字段,通过在query属性中增加{ '_source': '*' }来做限制,或在SDK的search函数中增加参数:

es.search(..., _source=['a', 'b'])

则返回的结果中只包含字段ab的值。

关于score

在搜索的结果项中,可以看到存在一个名为_score的参数,该参数表示了搜索结果的相关度。elasticsearch通过一定的匹配算法进行全文搜索,_score值越高,则结果越符合搜索需求(elasticsearch采用TF-IDF算法计算相关度)。
有时候我们需要过滤掉相关度过低的结果,例如,当搜索三国的时候,我们期望的结果是三国类的文本,例如三国志三国演义等,然而三字经等文本同样会被搜索到(后面会详细介绍原因)。在搜索体中指定最小允许的score值可以过滤不相关项:

search_body = {
    'query': {
        'match': {
            'a': 'ban',
        },
    },
    min_score: 5,
}
res = es.search(index='index', doc_type='type', body=search_body)

links

social