################ 基于词项和基于全文的搜索#####################
term查询
term查询不会对输入的词进行分词
批量添加三条测试文档
POST /products/_bulk
{ "index": { "_id": 1 }}
{ "productID" : "XHDK-A-1293-#fJ3","desc":"iPhone" }
{ "index": { "_id": 2 }}
{ "productID" : "KDKE-B-9947-#kL5","desc":"iPad" }
{ "index": { "_id": 3 }}
{ "productID" : "JODL-X-1937-#pV7","desc":"MBP" }
###可以看到文档被默认的dynamicmapping设置为text,并且是多字段,也包含了keyword
GET products
直接查询iPhone无法查询到,因为es采用了默认的standard 会将iPhone 处理为iphone 直接查询iphone就可以查询到结果
POST products/_search
{
"query": {
"term": {
"desc": {
//"value": "iPhone",
"value": "iphone"
}
}
}
}
测试iPhone分词结果
GET _analyze
{
"analyzer": "standard",
"text": ["iPhone"]
}
因为es在进行dynamic映射时有指定多字段,所以如果我们如果想要得到不分词的结果,可以使用字段.keyword进行查看 此时iphone 就不能得到查询结果了,而iPhone就可以得到查询结果
POST products/_search
{
"query": {
"term": {
"desc.keyword": {
//"value": "iPhone",
"value": "iphone"
}
}
}
}
同理,直接查询指定的id是不能获取结果的。因为在存储数据的时候,es对我们存入的词条进行了分词的处理
POST /products/_search
{
"query": {
"term": {
"productID": {
"value": "XHDK-A-1293-#fJ3"
}
}
}
}
此时通过字段.keyword就可以查询出所对应的数据 可以指定explain属性,查看查询的详情过程
POST /products/_search
{
"explain": true,
"query": {
"term": {
"productID.keyword": {
"value": "XHDK-A-1293-#fJ3"
}
}
}
}
符合查询 constant score 转为filter 在我们日常进行查询的时候,如果对于性能有要求,而且不需要es进行得分的计算,那么,我们可以将query 转为filter 忽略 TF-IDF算法计算得分,避免相关的算分的开心
###filter可以有效的利用缓存
POST /products/_search
{
"explain": true,
"query": {
"constant_score": {
"filter": {
"term": {
"productID.keyword": "XHDK-A-1293-#fJ3"
}
}
}
}
}
全文检索的查询
match Query match phrase query Query String Query
全文检索在搜索的过程中都会进行分词,查询的字符安次会先传递到一个合适的分词器,然后生成一个供查询的词项列表
查询时候,会先对输入的查询进行分词,然后每个词项逐个进行底层的查询,最终将结果进行合并,为每一个文档生成一个算分
https://blog.csdn.net/chuan442616909/article/details/56664861
我们使用 match_phrase 对于多值字段进行索引的时候。es对我们的数据进行分词,如果第一个词分为 1,2 第二个词分为3,4 即使我们使用match_phrase进行查询 2,3 也是能返回相应的结果,因为他们的分词位置是相邻的,我们可以通过设置position_increment_gap来指定每个次组之间的距离 这样就保证了查询结果的准确性,当然如果我们想要查询到这个词,那么只需在查询时,指定slop 就可以再次查询到这个词
###设置 position_increment_gap
###
DELETE groups
PUT groups
{
"mappings": {
"properties": {
"names":{
"type": "text",
"position_increment_gap": 0
}
}
}
}
GET groups/_mapping
POST groups/_doc
{
"names": [ "John Water", "Water Smith"]
}
GET groups/_search
{
"query": {
"match_phrase": {
"names": {
"query": "Water Water",
"slop": 100
}
}
}
}
当然,如果我们想要查询到更多的结果,就可以指定词组间隔为0 这样我们即使使用match_phrase 只要他们的顺序和查询顺序保持一致,我们都可以查询到结果
POST groups/_search
{
"query": {
"match_phrase": {
"names": "Water Smith"
}
}
}