因为项目需要调用api查询elasticsearch拿数据,这边记录一下项目中常用的一些查询参数

es的查询接口为:

GET /索引名/_search
python调用

data为需要传入的参数

import requests

res = requests.request("POST", f"http://127.0.0.1:9200/{index}/_search", json=data)

print(res.json())

一、常用查询关键字

1、match

match是模糊匹配查询,根据分词器(如果创建mapping没有指定分词器,Es将会采取默认的分词器:standard,standard分词将会把匹配的词组分成单个的字,而不是短语)将指定的query查询的语句进行分词匹配。

查询索引中name为Tom的文档:
{
    'query': {
        'match': {
            'name': 'Tom'
        }
    }
}

2、match_pharse

match_pharse属于短语匹配,要求查询的词句和匹配的短语顺序必须一致,并且是连续的,但可以设置 slop 值来指定查询项之间可以分隔多远的距离

查询索引中woke为程序员的文档:
{
    'query': {
        'match_pharse': {
            'woke': '程序员'
        }
    }
}

3、fuzzy

fuzzy查询的时候,不会根据分词器匹配,只会进行拆分,比如查询的是"海zei王",在分词器下(也就是match中)是无法匹配到单个词的,因为它不是一个短语,但是在fuzzy中是可以匹配的,并且fuzzy支持模糊和一定的容错查询匹配,因为它做的是匹配词的拆分,并不是短语。

查询索引中name为海zei王的文档:
{
    'query': {
        'fuzzy': {
            'name': '海zei王'
        }
    }
}

4、multi_match

多字段匹配,比如在查询test这个值的时候我们不仅需要在A这个字段中查询,同时它也有可能存在B中,按照普通的写法你可能需要写两次查询,但是使用了multi_search只需要指定具体的fields就可以实现多字段查询

同时在age字段和phone字段搜索包含38这个数字的文档:
{
    'query': {
        'multi_match': {
            'query': '38',
            'fields':['age','phone']
        }
    }
}

5、regexp

正则表达式匹配,该匹配模式下我们可以按照正则表达式的符号去匹配具体的值,比如name字段,可以包含有.和*去正则匹配具体的值,?表示任一字符,*表示所有字符,还有其他的正则符号都可以使用,详情参考Regexp Query | Elasticsearch Guide [6.8] | Elastic

匹配手机号以1到9之前的开头,并且第二位是3最后一位是0或者1的手机号的文档:
{
    'query': {
        'regexp': {
            'phone': {
                'value':'[1-9]3.*[0-1]'
            }
        }
    }
}

6、wildcard

通配符匹配,wildcard和regexp类似,不过它们也有不同之处。regexp的实际匹配能力要大于wildcard,在进行简单的匹配时候,比如名字的*或者?的简单普通匹配,建议使用wildcard而不是regexp,wildcard的效率要高于regexp,regexp可以实现更为复杂的场景,但是效率低一些,通俗的说wildcard是regexp的简化版本.

采用通配符匹配手机的电话号
{
    'query': {
        'wildcard': {
            'phone': '13643091*'
        }
    }
}

7、term

term的英文含义表示是:精确的意思,在term查询中,表示做的是精确查询,整词匹配,不会对所匹配项进行拆分。直接以整词进行匹配,如果能查询到就命中该文档

查询的name为鲁班的文档
{
    'query': {
        'term': {
            'name': {
                'value':'鲁班'
            }
        }
    }
}

8、 terms

terms和term的区别就是terms允许匹配多个值,而term只允许匹配一个值,在进行多值匹配的场景中可以使用terms,terms匹配到其中任何一个值就会认为整个文档是匹配的,terms多个值如果多个都匹配会返回所有文档

查询age为24、66的任一值,查到就返回文档
{
    'query': {
        'terms': {
            'age': ['24','36']
        }
    }
}

9、range

range表示一个区间范围查找,这个范围可以是日期或者数值,ES的range比较灵活和明确,可以指定两个边界是否包含,通过参数include_lower:true 、include_upper:true来控制

查询age为20到30区间所有文档,
include_lower表示是否包含边界最小值(true表示包含),
include_upper表示是否包含边界最大值(true表示包含,false表示不包含)

{
    'query': {
        'range': {
            'age': {
                'from': 20,
                'to': 30,
                'include_lower':true,
                'include_upper':false
                }
        }
    }
}

查询log_time对应时间区间内的所有文档,
gt/gt表示起始时间,gte包含起始时间点,gt不包含起始时间点,
lt/lte表示结束时间,lte包结束时间点,lt不包含结束时间点

{
    'query': {
        'range': {
                'log_time': {
                    'gte': '2022-04-02 00:00:00',
                    'lt': '2022-04-02 23:00:00',
                    'format': 'yyyy-MM-dd HH:mm:ss',
                }
            }
    }
}

二、组合多查询 

bool (布尔)过滤器。 这是个 复合过滤器(compound filter) ,它可以接受多个其他过滤器作为参数,并将这些过滤器结合成各式各样的布尔(逻辑)组合。

1、must

文档 必须must 匹配这些条件才能被包含进来,与 AND 等价。

must数组里面可以插入多个关键字查询条件
以下用例中查询sn为00000000, date_time为2022-04-02 00:00:00 到2022-04-02 23:00:00的文件
{
    'query': {
        'bool': {
                'must': [
                        {'terms': { 'sn': ['00000000']}},
                        {'range': {'date_time': {
                                'gt': '2022-04-02 00:00:00',
                                'lt': '2022-04-02 23:00:00',
                                'format': 'yyyy-MM-dd HH:mm:ss',
                            }}
                        }
                    ]
            }
    }
}

2、must_not

文档 必须不 must_not 匹配这些条件才能被包含进来,与 NOT 等价。

用例为:查询name不为李白的文件
{
    'query': {
        'bool': {
                'must_not': [
                        {'terms': { 'name': ['李白']}}
                    ]
            }
    }
}

 3、should

至少有一个语句要匹配,与 OR 等价

用例为:查询name为李白或者age为12 的文件
{
    'query': {
        'bool': {
                'should': [
                        {'terms': { 'name': ['李白']}},
                        {'term': { 'age': '12'}}
                    ]
            }
    }
}

4、filter 

必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。filter不会计算搜索条件相关度分数,也不会根据相关度分数进行排序,相对效率更高一些。

用例为:查询name为李白同的文件
{
    'query': {
        'bool': {
                'filter': [
                        {'terms': { 'name': ['李白']}}
                    ]
            }
    }
}

5、must、must_not、should组合用例 


以下用例中查询
sn为00000000, date_time为2022-04-02 00:00:00 到2022-04-02 23:00:00
或者name为Tom并且detail不以智能开头的文档
name为To
{
    'query': {
        'bool': {
                'must': [
                        {'terms': { 'sn': ['00000000']}},
                        {'range': {'date_time': {
                                'gt': '2022-04-02 00:00:00',
                                'lt': '2022-04-02 23:00:00',
                                'format': 'yyyy-MM-dd HH:mm:ss',
                            }}
                        }
                    ],
                'must_not': [
                        {'regexp': {'detail':'智能*'}}
                    ],
                'should': [
                        {'match': { 'name': 'Tom'}}
                   ]
            }
    }
}

三、分页和排序

分页检索,可以通过size和from来实现,size返回的条数,默认是10条,from返回的开始。

排序,可以根据sort来实现,该字段可以指定索引字段,也可以指定返回结果中的其他字段。

{
    "query":{
        "match_all":{}
    },
    "from":1,
    "size":10,
     "sort": {
           "age":"desc",
           "money":"asc"
       }
}

ElasticSearch的API使用 - Yrion - 博客园

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐