阅读es过滤相关文档
This commit is contained in:
@@ -699,7 +699,204 @@ GET /cooking_blog/_search
|
|||||||
> - 如果`total.relation`为`eq`,则`total.value`代表实际hit count
|
> - 如果`total.relation`为`eq`,则`total.value`代表实际hit count
|
||||||
> - 如果`total.relation`为`gte`, 则`total.value`为hit count的下界,实际hit count大于或等于`total.value`
|
> - 如果`total.relation`为`gte`, 则`total.value`为hit count的下界,实际hit count大于或等于`total.value`
|
||||||
|
|
||||||
|
> ##### max score
|
||||||
|
> `max_score`代表所有matching documents中最高的relevance score
|
||||||
|
|
||||||
|
> ##### _score
|
||||||
|
> _score为指定文档的relevance score,分数越高,匹配越好。
|
||||||
|
|
||||||
|
##### contains all terms
|
||||||
|
如上所示,如果在`query.match.description.query`中指定了多个由空格分隔的词,那么可以为`query.match.description.operator`指定`and`,那么其会查询description中包含所有分词的文档。
|
||||||
|
```
|
||||||
|
GET /cooking_blog/_search
|
||||||
|
{
|
||||||
|
"query": {
|
||||||
|
"match": {
|
||||||
|
"description": {
|
||||||
|
"query": "fluffy pancakes",
|
||||||
|
"operator": "and"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 应匹配terms的最小个数
|
||||||
|
通过`minimum_should_match`参数,可以指定在search result中最少应该匹配的terms个数。
|
||||||
|
|
||||||
|
如下实例中,查询文本中包含三个分词,`"fluffy", "pancakes", or "breakfast"`,但是查询结果中至少应该包含3个中的2个:
|
||||||
|
```
|
||||||
|
GET /cooking_blog/_search
|
||||||
|
{
|
||||||
|
"query": {
|
||||||
|
"match": {
|
||||||
|
"title": {
|
||||||
|
"query": "fluffy pancakes breakfast",
|
||||||
|
"minimum_should_match": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
##### search across mutli fields
|
||||||
|
当用户输入查询文本时,其通常不知道是否查询文本出现在文档中的哪个字段。`multi_match`允许同时跨多个字段来进行查询。
|
||||||
|
|
||||||
|
mutli_match查询示例如下:
|
||||||
|
```
|
||||||
|
GET /cooking_blog/_search
|
||||||
|
{
|
||||||
|
"query": {
|
||||||
|
"multi_match": {
|
||||||
|
"query": "vegetarian curry",
|
||||||
|
"fields": ["title", "description", "tags"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
在上述示例中,将会在`title, description, tags`三个字段中查询`vegetarian curry`,其中每个字段的重要性都相同。
|
||||||
|
|
||||||
|
但是,在某种场景下,在部分字段中的匹配比其他字段中的匹配更加重要(例如,相关论文检索时,关键词出现在摘要中要比出现在正文中更加重要)。
|
||||||
|
|
||||||
|
因此,可以在fields中针对多个字段进行重要性加权的调整:
|
||||||
|
```
|
||||||
|
GET /cooking_blog/_search
|
||||||
|
{
|
||||||
|
"query": {
|
||||||
|
"multi_match": {
|
||||||
|
"query": "vegetarian curry",
|
||||||
|
"fields": ["title^3", "description^2", "tags"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
如上述示例所示,`^`语法应用于指定字段:
|
||||||
|
- `title^3`:title的重要性为非增强字段的3倍
|
||||||
|
- `description^2`:description的重要性为非增强字段的2倍
|
||||||
|
- `tags`:非增强字段
|
||||||
|
|
||||||
|
#### filter & exact matches
|
||||||
|
filter允许根据指定条件来缩小查询结果的范围。和full-text search不同的是,filter是二进制的,并且不会影响relevance score。
|
||||||
|
|
||||||
|
filter相较于query执行的更快,因为被排除的result不会计算score。
|
||||||
|
|
||||||
|
##### bool query
|
||||||
|
在如下示例中,`bool query`只会返回category为`Breakfast`中的文档:
|
||||||
|
```
|
||||||
|
GET /cooking_blog/_search
|
||||||
|
{
|
||||||
|
"query": {
|
||||||
|
"bool": {
|
||||||
|
"filter": [
|
||||||
|
{ "term": { "category.keyword": "Breakfast" } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
在针对`category`进行filter时,指定的是`category.keyword`,其类型为`keyword`,为`精确、区分大小写的匹配`。
|
||||||
|
|
||||||
|
> `category.keyword`字段其`multi field`类型为`keyword`,代表了字段`没有经过分析的版本`(代表字段没有指定analyzer),故而其进行的是精确、大小写敏感的匹配。
|
||||||
|
>
|
||||||
|
> 如下两种场景将会使用`.keyword`:
|
||||||
|
> 1. 使用了针对`text`类型的字段使用了dynamic mappings,此时es会自动创建一个名为`.keyword`的`multi-field`
|
||||||
|
> 2. 当手动指定`text`类型字段的`.keyword`为`keyword`类型时
|
||||||
|
|
||||||
|
##### date range
|
||||||
|
当想要查询一定时间范围内的文档时,可以按如下方式来编写查询:
|
||||||
|
```
|
||||||
|
GET /cooking_blog/_search
|
||||||
|
{
|
||||||
|
"query": {
|
||||||
|
"range": {
|
||||||
|
"date": {
|
||||||
|
"gte": "2023-05-01",
|
||||||
|
"lte": "2023-05-31"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
##### exact match
|
||||||
|
可以通过`term`来搜索精确术语,term将会在字段中精确的搜索,`并不会对传入的文本进行分析`。
|
||||||
|
|
||||||
|
针对指定term的精确、大小写敏感搜索通常基于keyword进行搜索。
|
||||||
|
|
||||||
|
term搜索示例如下所示,搜索作者为`Maria Rodriguez`的文档:
|
||||||
|
```
|
||||||
|
GET /cooking_blog/_search
|
||||||
|
{
|
||||||
|
"query": {
|
||||||
|
"term": {
|
||||||
|
"author.keyword": "Maria Rodriguez"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 应该避免在`text`类型的字段上使用`term`查询,因为`text`类型的field会被analyzer进行分析和转换
|
||||||
|
|
||||||
|
#### 组合搜索
|
||||||
|
`bool query`允许将多个子查询组合为复杂的查询。
|
||||||
|
|
||||||
|
bool query示例如下:
|
||||||
|
```
|
||||||
|
GET /cooking_blog/_search
|
||||||
|
{
|
||||||
|
"query": {
|
||||||
|
"bool": {
|
||||||
|
"must": [
|
||||||
|
{ "term": { "tags": "vegetarian" } },
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"rating": {
|
||||||
|
"gte": 4.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"term": {
|
||||||
|
"category": "Main Course"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"multi_match": {
|
||||||
|
"query": "curry spicy",
|
||||||
|
"fields": [
|
||||||
|
"title^2",
|
||||||
|
"description"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"date": {
|
||||||
|
"gte": "now-1M/d"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"must_not": [
|
||||||
|
{
|
||||||
|
"term": {
|
||||||
|
"category.keyword": "Dessert"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
上述查询含义如下:
|
||||||
|
- tag中必须精确匹配vegetarian
|
||||||
|
- rating必须大于或等于4.5
|
||||||
|
- 在title或者description中应该包含`curry`或`spicy`
|
||||||
|
- category应该精确匹配`Main Course`
|
||||||
|
- date字段应该大于或等于上个月
|
||||||
|
- category不能为Dessert
|
||||||
|
|
||||||
|
> ##### `must_not`
|
||||||
|
> `must_not`会淘汰不满足指定条件的文档
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user