ElaticSearch进阶(1)_使用term filter来搜索数据

ElaticSearch使用term filter来搜索数据

1.插入测试数据

1.1 回忆批量操作_bulk

语法

{action:{metadata}}\n
{request body}\n
{action:{metadata}}\n
{request body}\n
.....
action行为 解释
create 当文档不存在时进行创建
index 创建新文档或替换已有文档
update 局部更新文档
delete 删除一个文档

例如:

{"delete":{"_index":"library","_type":"books","_id":"1"}}

其他action的演示
ElaticSearch进阶(1)_使用term filter来搜索数据_第1张图片

1.2 插入测试数据

POST /forum/article/_bulk
{ "index": { "_id": 1 }}
{ "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 2 }}
{ "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" }
{ "index": { "_id": 3 }}
{ "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 4 }}
{ "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }

注意:最后一行也要进行换行,不然会报错

初步来说,就先搞4个字段,因为整个es是支持json document格式的,所以说扩展性和灵活性非常之好。如果后续随着业务需求的增加,要在document中增加更多的field,那么我们可以很方便的随时添加field。


2.根据用户ID搜索帖子

GET /forum/article/_search
{
    "query" : {
        "constant_score" : { 
            "filter" : {
                "term" : { 
                    "userID" : 1
                }
            }
        }
    }
}
  • term:对搜索文本不分词,直接拿去倒排索引中匹配,你输入的是什么,就去匹配什么
    例如:“hello world” --> “hello world”,直接去倒排索引中匹配“hello world”

注意点:所以就会产生一个问题,比如我们在demo(索引)下新增这4个文档
在这里插入图片描述
当我们使用term去搜索"spotless future"时无法搜索到结果

原因在于:分词器将"spotless future"分析成"spotless"和"future"作为关键词,生成到倒排索引的检索目录中

GET /demo/_analyze
{
  "field": "text",
  "text": "Whatever your past has been, you have a spotless future"
}

通过term,将"spotless future"作为一个关键词去倒排索引中匹配,当然是无法匹配的

替代的查询方法:match_phrase

3.搜索没有隐藏的帖子

GET /forum/article/_search
{
    "query" : {
        "constant_score" : { 
            "filter" : {
                "term" : { 
                    "hidden" : false
                }
            }
        }
    }
}

4.根据发帖日期搜索帖子

GET /forum/article/_search
{
    "query" : {
        "constant_score" : { 
            "filter" : {
                "term" : { 
                    "postDate" : "2017-01-01"
                }
            }
        }
    }
}

5.根据帖子ID搜索帖子

GET /forum/article/_search
{
    "query" : {
        "constant_score" : { 
            "filter" : {
                "term" : { 
                    "articleID" : "XHDK-A-1293-#fJ3"
                }
            }
        }
    }
}

搜索结果为空,为什么查不到呢?
ElaticSearch进阶(1)_使用term filter来搜索数据_第2张图片

  • articleID.keyword,是es最新版本内置建立的field,就是不分词的。
  • 所以一个articleID过来的时候,会建立两次索引,一次是自己本身,是要分词的,分词后放入倒排索引;
  • 另外一次是基于articleID.keyword,不分词,保留256个字符最多,直接一个字符串放入倒排索引中
  • 所以term filter,对text过滤,可以考虑使用内置的field.keyword来进行匹配。
  • 但是有个问题,默认就保留256个字符。所以尽可能还是自己去手动建立索引,指定not_analyzed吧。在最新版本的es中,不需要指定not_analyzed也可以,将type=keyword即可。

使用field.keyword进行匹配

GET /forum/article/_search
{
    "query" : {
        "constant_score" : { 
            "filter" : {
                "term" : { 
                    "articleID.keyword" : "XHDK-A-1293-#fJ3"
                }
            }
        }
    }
}

扩展:

当我们插入的数据是text类型时,例如插入"articleID":“XHDK-A-1293-#fJ3”,在mappings中,除了原本的articleID字段,在articleID字段下还有一个keyword字段

  • articleID的type表示自己本身,是要分词的,分词后放入倒排索引
  • articleID.keyword的type是不分词的,直接将字符串放入倒排索引中
验证articleID的分词
GET /forum/_analyze
{
  "field": "articleID",
  "text": "XHDK-A-1293-#fJ3"
}

分词器将 "XHDK-A-1293-#fJ3"分成"xhdk","a","1293","fj3"放入倒排索引中(字段为articleID)

验证articleID.keyword的分词
GET /forum/_analyze
{
  "field": "articleID.keyword",
  "text": "XHDK-A-1293-#fJ3"
}
直接将"XHDK-A-1293-#fJ3"扔到倒排索引中(字段为articleID.keyword)

6.查看分词

GET /forum/_analyze
{
  "field": "articleID",
  "text": "XHDK-A-1293-#fJ3"
}
  • 默认是analyzed的text类型的field,建立倒排索引的时候,就会对所有的articleID分词,分词以后,原本的articleID就没有了,只有分词后的各个word存在于倒排索引中。
  • term,是不对搜索文本分词的,XHDK-A-1293-#fJ3 --> XHDK-A-1293-#fJ3;但是articleID建立索引的时候,XHDK-A-1293-#fJ3 --> xhdk,a,1293,fj3

7.重建索引

DELETE /forum

PUT /forum
{
  "mappings": {
    "article": {
      "properties": {
        "articleID": {
          "type": "keyword"
        }
      }
    }
  }
}

POST /forum/article/_bulk
{ "index": { "_id": 1 }}
{ "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 2 }}
{ "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" }
{ "index": { "_id": 3 }}
{ "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 4 }}
{ "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }

当articleID的类型指定为keyword,就不会进行分词了
ElaticSearch进阶(1)_使用term filter来搜索数据_第3张图片

8.重新根据帖子ID和发帖日期进行搜索

{
    "query" : {
        "constant_score" : { 
            "filter" : {
                "term" : { 
                    "articleID" : "XHDK-A-1293-#fJ3"
                }
            }
        }
    }
}

总结:

  • term filter:根据exact value进行搜索,数字、boolean、date天然支持
  • text需要建索引时指定为not_analyzed,才能用term query
  • 相当于SQL中的单个where条件
select *
from forum.article
where articleID='XHDK-A-1293-#fJ3'

你可能感兴趣的:(ElasticSearch,term)