后端开发之Elasticsearch篇----DSL

Elasticsearch的DSL风格

非DSL风格的查询方式

查询[字段]包含[内容]的文档

# 可以理解为在全文搜索的基础上添加了查询字段的筛选
GET     /shop/_doc/_search?q=desc:doudou
GET     /shop/_doc/_search?q=nickname:men&q=age:25

text与keyword搜索对比测试(keyword不会被倒排索引,不会被分词)

# 这里nickname中的格式是text而username是keyword
# 如果是text格式的话,会对super hero进行分词;如果是keyword则不会
GET     /shop/_doc/_search?q=nickname:super
GET     /shop/_doc/_search?q=username:super
GET     /shop/_doc/_search?q=username:super hero

以上方式称之为QueryString查询方式,参数都是放在url中作为请求参数的。

DSL基础语法

match和exists

分词匹配和是否存在某字段

# 查询指定字段含有某些词汇
POST     /shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "doudou"
        }
    }
}
# 判断某个字段是否存在
{
    "query": {
        "exists": {
	        "field": "desc"
	    }
    }
}
match_all

查询全部和分页

# url方式
GET     /shop/_doc/_search

# DSL方式,使用了match_all的关键字
# _source用于指定要展现的字段和select后面接的字段是一致的
POST     /shop/_doc/_search 
{
    "query": {
        "match_all": {}
    },
    "_source": ["id", "nickname", "age"]
}

在header中使用界面的操作
在这里插入图片描述
分页查询,默认只有10条记录

# 在query同级下面添加关键字from和size,其中from指记录的下标,size为单页的记录条数
POST     /shop/_doc/_search
{
    "query": {
        "match_all": {}
    },
    "from": 0,
    "size": 10
}

{
	"query": {
		"match_all": {}
	},
	"_source": [
		"id",
		"nickname",
		"age"
	],
	"from": 5,
	"size": 5
}

在这里插入图片描述

term

term和match的区别,其实两者都是查询含有指定词汇的字段,但是match会对我们输入的词汇进行再分词,而term就是精确匹配

POST     /shop/_doc/_search
{
    "query": {
        "term": {
            "desc": "大学城" # 就直接用大学城查
        }
    }
}
对比
{
    "query": {
        "match": {
            "desc": "大学城" # 会先对大学城进行分词,eg:大学,城,大...再进行分词
        }
    }
}

header的操作
在这里插入图片描述

terms

多词匹配检索

POST     /shop/_doc/_search
{
    "query": {
        "terms": {
            "desc": ["慕课网", "学习", "骚年"] # 默认是or操作
        }
    }
}
match_phrase

短语匹配
match:分词后只要有匹配就返回,match_phrase:分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。(搜索比较严格)

  • slop:允许词语间跳过的数量
POST     /shop/_doc/_search
{
    "query": {
        "match_phrase": {
            "desc": {
            	"query": "大学 毕业 研究生",
            	"slop": 2 # 允许大学和毕业和研究生之间相隔的词汇少于等于2个,不要求紧挨着
            }
        }
    }
}
operator

match扩展:operator

  • and
  • or 默认情况下是使用or的
POST     /shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "慕课网"
        }
    }
}
# 等同于
{
    "query": {
        "match": {
            "desc": {
                "query": "xbox游戏机",
                "operator": "or"
            }
        }
    }
}
# 相当于 select * from shop where desc='xbox' or|and desc='游戏机'

在使用and的时候如果想降低标准可以使用minimum_should_match这个关键词来标记、

  • minimum_should_match:
    最低匹配精度,至少有[分词后的词语个数]x百分百,得出一个数据值取整。举个例子:当前属性设置为70,若一个用户查询检索内容分词后有10个词语,那么匹配度按照
    10x70%=7,则desc中至少需要有7个词语匹配,就展示;若分词后有8个,则
    8x70%=5.6,则desc中至少需要有5个词语匹配,就展示。
POST     /shop/_doc/_search
{
    "query": {
        "match": {
            "desc": {
                "query": "女友生日送我好玩的xbox游戏机",
                "minimum_should_match": "60%"
            }
        }
    }
}
ids

根据文档主键进行搜索

# url方式
GET /shop/_doc/1001

# DSL风格
POST     /shop/_doc/_search
{
    "query": {
        "ids": {
            "type": "_doc", # 要加一个文档类型,新版只有_doc了
            "values": ["1001", "1010", "1008"]
        }
    }
}
  • multi_match满足match的多个匹配方式
# 匹配的词汇会在多个字段中查询
POST     /shop/_doc/_search
{
    "query": {
        "multi_match": {
                "query": "皮特帕克慕课网",
                "fields": ["desc", "nickname"]

        }
    }
}

因为显示是根据权重(分数)来排序的,可以通过boost来改变显示顺序

POST     /shop/_doc/_search
{
    "query": {
        "multi_match": {
                "query": "皮特帕克慕课网",
                "fields": ["desc", "nickname^10"] # 就是这个^符号,现在就以nickname要标准
        }
    }
}

nickname^10 代表搜索提升10倍相关性,也就是说用户搜索的时候其实以这个nickname为主,desc为辅,nickname的匹配相关度当然要提高权重比例了。

布尔查询
  • must 所有条件都必须命中
  • must_not 所有条件不能命中
  • should 只要满足其中一条就可以了
    以上3个关键字可以同时使用,和query都是同级的
POST     /shop/_doc/_search

{
    "query": {
        "bool": {    # 使用布尔查询需要先标注这个关键字
            "must": [
                {
                    "multi_match": {
                        "query": "慕课网",
                        "fields": ["desc", "nickname"]
                    }
                },
                {
                    "term": {
                        "sex": 1
                    }
                },
                {
                    "term": {
                        "birthday": "1996-01-14"
                    }
                }
            ]
        }
    }
}

{
    "query": {
        "bool": {
            "should(must_not)": [
                {
                    "multi_match": {
                        "query": "学习",
                        "fields": ["desc", "nickname"]
                    }
                },
                {
                	"match": {
                		"desc": "游戏"
                	}	
                },
                {
                    "term": {
                        "sex": 0
                    }
                }
            ]
        }
    }
}
POST  /shop/_doc/_search
{
    "query": {
        "bool": {
            "must": [
                {
                	"match": {
                		"desc": "慕"
                	}	
                },
                {
                	"match": {
                		"nickname": "慕"
                	}	
                }
            ],
            "should": [
                {
                	"match": {
                		"sex": "0"
                	}	
                }
            ],
            "must_not": [
                {
                	"term": {
                		"birthday": "1992-12-24"
                	}	
                }
            ]
        }
    }
}

在这里插入图片描述

boost

为指定词语加权

POST     /shop/_doc/_search
{
    "query": {
        "bool": {
            "should": [
            	{
            		"match": {
            			"desc": {
            				"query": "律师",
            				"boost": 18
            			}
            		}
            	},
            	{
            		"match": {
            			"desc": {
            				"query": "进修",
            				"boost": 2
            			}
            		}
            	}
            ]
        }
    }
}
post_filter

使用post_filter过滤器,但是这个过滤器是在检索出来的结果上再进行过滤,这样的操作效率会更高,所以其和query是同级的关键字

  • gt 大于
  • lt 小于
  • gte 大于等于
  • lte 小于等于

这里还配合了range关键字使用,使用上述关键字前要使用

POST     /shop/_doc/_search

{
	"query": {
		"match": {
			"desc": "慕课网游戏"
		}	
    },
    "post_filter": {
		"range": {
			"money": {
				"gt": 60,
				"lt": 1000
			}
		}
	}	
}
sort

排序
和query,post_filter等关键字同级,不能对text数据类型进行排序,如果需要对有text属性的字段排序的话,需要为这个字段添加一个附属属性表明是keyword类型

POST     /shop/_doc/_search
{
	"query": {
		"match": {
			"desc": "慕课网游戏"
		}
    },
    "post_filter": {
    	"range": {
    		"money": {
    			"gt": 55.8,
    			"lte": 155.8
    		}
    	}
    },
    "sort": [ # 后面接的是一个数组
        {
            "age": "desc"
        },
        {
            "money": "desc"
        }
    ]
}

创建mappings时要主要的添加附属属性

POST        /shop2/_mapping
{
    "properties": {
        "id": {
            "type": "long"
        },
        "nickname": {
            "type": "text",
            "analyzer": "ik_max_word",
            "fields": {
                "keyword": {
                    "type": "keyword"
                }
            }
        }
    }
}

使用附属属性进行排序时,注意添加附属属性的名称

{
    "sort": [
        {
            "nickname.keyword": "desc"
        }
    ]
}
highlight

高亮显示
其中pre_tags和post_tags这两个关键字使用用于对要高亮的词语的前后标注
百度使用的是em标签,而阿里使用的是span标签

POST     /shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "慕课网"
        }
    },
    "highlight": {
        "pre_tags": ["<tag>"],
        "post_tags": ["</tag>"],
        "fields": {
            "desc": {}
        }
    }
}
prefix

根据前缀前查询

POST     /shop/_doc/_search
{
    "query": {
        "prefix": {
            "desc": "imo"
        }
    }
}
fuzzy

模糊搜索,并不是指的sql的模糊搜索,而是用户在进行搜索的时候的打字错误现象,搜索引擎会自动纠正,然后尝试匹配索引库中的数据。

POST     /shop/_doc/_search
{
  "query": {
    "fuzzy": {
      "desc": "imoov.coom"
    }
  }
}
# 或多字段搜索
{
  "query": {
    "multi_match": {
      "fields": [ "desc", "nickname"],
      "query": "imcoc supor",
      "fuzziness": "AUTO"
    }
  }
}

{
  "query": {
    "multi_match": {
      "fields": [ "desc", "nickname"],
      "query": "演说",
      "fuzziness": "1"
    }
  }
}
wildcard

占位符查询

  • ?:1个字符
  • *:1个或多个字符
POST     /shop/_doc/_search
{
  "query": {
    "wildcard": {
      "desc": "*oo?"
    }
  }
}
{
	"query": {
    	"wildcard": {
    		"desc": "演*"
    	}
	}
}

前缀和占位符两种查询相对于term的精确查询没那么严格,但是和match查询来说其匹配模式更精确一点吧

发布了118 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_39702831/article/details/104961207
今日推荐