elasticsearch研习(一)

GET _search
{
  "query": {
    "match_all": {}
  }
}

# 添加一条记录,由于是添加首条记录,所以可能比较慢一点
PUT t1/doc/1
{
 "name": "小黑的小姨妈",
 "age": 18
}

PUT t1/doc/2
{
 "name": "小黑的二姨妈",
 "age": 16
}

PUT t1/doc/3
{
 "name": "小黑的三姨妈",
 "age": 19
}

# 查看创建的文档
GET t1/doc/3

# 查看t1索引
GET t1

# 查看索引情况
GET _cat/indices?v


#查询所有文档
GET t1/doc/_search

#删除索引
DELETE /t1

#CURD
# C 创建、添加
#初始化创建索引、类型、文档
PUT zhifou/doc/1
{
  "name":"顾老二",
  "age":30,
  "from": "gu",
  "desc": "皮肤黑、武器长、性格直",
  "tags": ["黑", "长", "直"]
}

# 继续添加
PUT zhifou/doc/2
{
  "name":"大娘子",
  "age":18,
  "from":"sheng",
  "desc":"肤白貌美,娇憨可爱",
  "tags":["白", "富","美"]
}
# 继续添加
PUT zhifou/doc/3
{
  "name":"龙套偏房",
  "age":22,
  "from":"gu",
  "desc":"mmp,没怎么看,不知道怎么形容",
  "tags":["造数据", "真","难"]
}

PUT zhifou/doc/4
{
  "name":"石头",
  "age":29,
  "from":"gu",
  "desc":"粗中有细,狐假虎威",
  "tags":["粗", "大","猛"]
}

PUT zhifou/doc/5
{
  "name":"魏行首",
  "age":25,
  "from":"广云台",
  "desc":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!",
  "tags":["闭月","羞花"]
}

#当执行PUT命令时,如果数据不存在,则新增该条数据,如果数据在则修改该条数据。直接对一个已经存在的文档进行PUT操作会导致整个记录被覆盖更新,进而会丢失数据,下面的举例就是对这种情况的演示,这种情况显然是不合适的

# 查询
GET zhifou/doc/1

PUT zhifou/doc/1
{
  "desc":"皮肤很黄,武器很长,性格很直",
  "tags":["很黄","很长", "很直"]
}

GET zhifou/doc/1

#CURD 之U update
# 恢复现场
PUT zhifou/doc/1
{
  "name":"顾老二",
  "age":30,
  "from": "gu",
  "desc": "皮肤黑、武器长、性格直",
  "tags": ["黑", "长", "直"]
}

POST zhifou/doc/1/_update
{
  "doc": {
    "desc": "皮肤很黄,武器很长,性格很直",
    "tags": ["很黄","很长", "很直"]
  }
}

# 查看更新符合预期
GET zhifou/doc/1

#注意:POST命令,这里可用来执行修改操作(还有其他的功能),POST命令配合_update完成修改操作,指定修改的内容放到doc中。

#CURD 之 D
#删除
DELETE zhifou/doc/4

#删除确认
GET zhifou/doc/4

#CURD 之 R
GET zhifou/doc/1

GET zhifou/doc/_search?q=from:gu
#我们来重点说下hits,hits是返回的结果集——所有from属性为gu的结果集。重点中的重点是_score得分,得分是什么呢?根据算法算出跟查询条件的匹配度,匹配度高得分就高。后面再说这个算法是怎么回事。

#推荐使用这种方式进行查询
GET zhifou/doc/_search
{
  "query": {
    "match": {
      "from": "gu"
    }
  }
}

#match 之match_all
GET zhifou/doc/_search
{
  "query": {
    "match_all": {}
  }
}

#match系列之match_phrase(短语查询)

#数据准备
PUT t1/doc/1
{
  "title": "中国是世界上人口最多的国家"
}
PUT t1/doc/2
{
  "title": "美国是世界上军事实力最强大的国家"
}
PUT t1/doc/3
{
  "title": "北京是中国的首都"
}

#查询所有文档
GET t1/doc/_search
GET t1/doc/_search
{
  "query": {
    "match_all": {}
  }
}

#虽然如期的返回了中国的文档。但是却把和美国的文档也返回了,这并不是我们想要的。
GET t1/doc/_search
{
  "query": {
    "match": {
      "title": "中国"
    }
  }
}

#针对上面的问题,短语查询就出现了
GET t1/doc/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "中国"
      }
    }
  }
}

#下面我们要搜索包含中国,又包含世界 文档呢?
GET t1/doc/_search
{
  "query": {
    "match_phrase": {
      "title": "中国世界"
    }
  }
}
#结果集是空,显然这不合适。

#于是就有了分词查询的初步
#slop是允许有5个以内的字符间隔
GET t1/doc/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "中国世界",
        "slop": 5
      }
    }
  }
}

#match系列之match_phrase_prefix(最左前缀查询)
#数据准备
PUT t3/doc/1
{
  "title": "maggie",
  "desc": "beautiful girl you are beautiful so"
}
PUT t3/doc/2
{
  "title": "sun and beach",
  "desc": "I like basking on the beach"
}

#现在凌晨2点半,单身狗小黑为了缓解寂寞,就准备搜索几个beautiful girl来陪伴自己。但是由于英语没过2级,但单词beautiful拼到bea就不知道往下怎么拼了。这个时候,我们的智能搜索要帮他啊,elasticsearch就看自己的词库有啥事bea开头的词

#但这里用match和match_phrase都不太合适,因为小黑输入的不是完整的词。那怎么办呢?我们用match_phrase_prefix来搞
GET t3/doc/_search
{
  "query": {
    "match_phrase_prefix": {
      "desc": "bea"
    }
  }
}

#前缀查询是短语查询类似,但前缀查询可以更进一步的搜索词组,只不过它是和词组中最后一个词条进行前缀匹配(如搜这样的you are bea)。应用也非常的广泛,比如搜索框的提示信息,当使用这种行为进行搜索时,最好通过max_expansions来设置最大的前缀扩展数量,因为产生的结果会是一个很大的集合,不加限制的话,影响查询性能。
GET t3/doc/_search
{
  "query": {
    "match_phrase_prefix": {
      "desc": {
        "query": "bea",
        "max_expansions": 1
      }

    }
  }
}
#虽然结果没有变化,但是据说底层会有性能机制改进
#我们快刀斩乱麻的记住,使用前缀查询会非常的影响性能,要对结果集进行限制,就加上这个参数


#match系列之multi_match(多字段查询)
#数据准备
PUT t3/doc/1
{
  "title": "maggie is beautiful girl",
  "desc": "beautiful girl you are beautiful so"
}
PUT t3/doc/2
{
  "title": "beautiful beach",
  "desc": "I like basking on the beach,and you? beautiful girl"
}

#查询准备信息
GET t3/doc/_search

#如果我们要查询title字段和desc字段中有beatiful的文档呢?
#朴实的做法
GET t3/doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "beautiful"
          }
        },
        {
          "match": {
            "desc": "beautiful"
          }
        }
      ]
    }
  }
}
#更好的办法
GET t3/doc/_search
{
  "query": {
    "multi_match": {
      "query": "beautiful",
      "fields": ["title", "desc"]
    }
  }
}
#使用must来限制两个字段(值)中必须同时含有关键字。这样虽然能达到目的,但是当有很多的字段呢,我们可以用multi_match来做
#除此之外,multi_match甚至可以当做match_phrase和match_phrase_prefix使用,只需要指定type类型即可:

GET t3/doc/_search
{
  "query": {
    "multi_match": {
      "query": "gi",
      "fields": ["title"],
      "type": "phrase_prefix"
    }
  }
}

GET t3/doc/_search
{
  "query": {
    "multi_match": {
      "query": "girl",
      "fields": ["title"],
      "type": "phrase"
    }
  }
}

#
#match:返回所有匹配的分词。
#match_all:查询全部。
#match_phrase:短语查询,在match的基础上进一步查询词组,可指定slop分词间隔。
#match_phrase_prefix:前缀查询,根据短语中最后一个词组做前缀匹配,可以应用于搜索提示,但注意和max_expanions搭配。其实默认是50.......
#multi_match:多字段查询,使用相当的灵活,可以完成match_phrase和match_phrase_prefix的工作。



#默认情况下,elasticsearch在对文档分析期间(将文档分词后保存到倒排索引中),会对文档进行分词,比如默认的标准分析器会对文档进行:
#   删除大多数的标点符号。
#   将文档分解为单个词条,我们称为token。
#    将token转为小写。

#完事再保存到倒排索引上,当然,原文件还是要保存一分的,而倒排索引使用来查询的。
#例如Beautiful girl!,在经过分析后是这样的了:

# 下面是示例
POST _analyze
{
  "analyzer": "standard",
  "text": "Beautiful girl!"
}
#搜索结果中的示例token全是小写


#而当在使用match查询时,elasticsearch同样会对查询关键字进行分析,这在需要这么做的时候自然很好,但是如果不需要呢?
# 如下示例
PUT w10
{
  "mappings": {
    "doc":{
      "properties":{
        "t1":{
          "type": "text"
        }
      }
    }
  }
}

PUT w10/doc/1
{
  "t1": "Beautiful girl!"
}
PUT w10/doc/2
{
  "t1": "sexy girl!"
}
GET w10/doc/_search
{
  "query": {
    "match": {
      "t1": "Beautiful girl!"
    }
  }
}
#如果我们就想查询准确包含Beautiful girl!的结果呢?

#这就要用到了term查询了,term查询的是没有经过分析的查询关键字。
GET w10/doc/_search
{
  "query": {
    "term": {
      "t1": "Beautiful girl!"
    }
  }
}
#但是执行这个查询结果后,你发现是空。
#为什么呢?
#因为elasticsearch在执行文本分析的时候做过手脚,大写变小写,去除标点符号等。

GET w10/doc/_search
{
  "query": {
    "term": {
      "t1": "beautiful girl"
    }
  }
}
# 还是不行,又是为什么呢?
#如上面的查询,将不会有结果返回,因为索引w10中的两篇文档在经过elasticsearch分析后没有一个分词是Beautiful girl!,那此次查询结果为空也就好理解了。
#所以,我们这里得到一个论证结果:不要使用term对类型是text的字段进行查询,要查询text类型的字段,请改用match查询。
#学会了吗?那再来一个示例,你说一下结果是什么:

# 这个应该有结果吧
GET w10/doc/_search
{
  "query": {
    "term": {
      "t1": "beautiful"
    }
  }
}

GET w10/doc/_search
{
  "query": {
    "terms": {
      "t1": ["beautiful", "girl"]
    }
  }
}
#其实这个地方还有很多扩展。
#https://www.cnblogs.com/Neeo/articles/10578482.html#match%E7%B3%BB%E5%88%97%E4%B9%8Bmulti_match%E5%A4%9A%E5%AD%97%E6%AE%B5%E6%9F%A5%E8%AF%A2


转载摘要来自于
https://www.cnblogs.com/Neeo/articles/10304892.html

非常感谢,创作者的无私分享。

版权声明:除特别注明外,本站所有文章均为王晨曦个人站点原创

转载请注明:出处来自王晨曦个人站点 » elasticsearch研习(一)

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注