es使用term+filter查询(对type为text的查询注意点)

摘要:
“UserID”:{“properties”:“fields”:“hidden”:“long”:“Search”}查询ID为2/的完全匹配的GET/forum/article搜索{“Query”:Query articleIDGET/forum/article/_Search{”查询“:{”术语“:GET/for论坛/article _Search”查询

插入测试数据

PUT /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" }

查看生成的mapping:

GET /forum/_mapping/article

结果(articleID除了显示type外,还有一个fields显示):

type=text,默认会设置两个field,一个是field本身,比如articleID就是分词的;还有一个就是field.keyword(这里是articleID.keyword),这个字段默认是不分词的,并且最多保留256字符
{
  "forum": {
    "mappings": {
      "article": {
        "properties": {
          "articleID": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "hidden": {
            "type": "boolean"
          },
          "postDate": {
            "type": "date"
          },
          "userID": {
            "type": "long"
          }
        }
      }
    }
  }
}

查询id为2的精确匹配

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "userID": "1"
        }
      },
      "boost": 1.2
    }
  }
}

constant_score:返回确切的得分

query+constant_score+filter+term:查找

term和terms的区别:terms是term的复数形式,用法 "terms": {"userID": ["1","2"]},term精确匹配一个,而terms是精确匹配多个值。

查询articleID

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

引用语句:结果为空。因为articleID.keyword,是ES最新版本内置建立的field,就是不分词的。所以一个articleID过来的时候,会建立两次索引。一次是自己本身(articleID),是要分词的,分词后放入倒排索引;另一次是基于articleID.keyword,不分词,最多保留256字符,直接一个完整的字符串放入倒排索引中。

所以term filter,对text过滤,可以考虑使用内置的field.keyword来进行匹配。但是有个问题,默认就保留256字符,所以尽可能还是自己去手动建立索引,指定not_analyzed吧,在最新版本的es中,不需要指定not_analyzed也可以,将type=keyword即可。

自己的理解:term是精确查找,去找XHDK-A-1293-#fJ3

                    问题是创建索引的时候,默认对text进行分词后简历索引。所以查询不到。

                    但是keyword是未被分词后索引,索引这种查找能查询出来。

解决方法:

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

更深度的理解,分词后的索引:

GET /forum/_analyze
{
  "field": "articleID",
  "text": "XHDK-A-1293-#fJ3"
}

结果:

{
  "tokens": [
    {
      "token": "xhdk",
      "start_offset": 0,
      "end_offset": 4,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "a",
      "start_offset": 5,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "1293",
      "start_offset": 7,
      "end_offset": 11,
      "type": "<NUM>",
      "position": 2
    },
    {
      "token": "fj3",
      "start_offset": 13,
      "end_offset": 16,
      "type": "<ALPHANUM>",
      "position": 3
    }
  ]
}

多条件查询一:select * from forum.article where (post_date='2017-01-01' or article_id='XHDK-A-1293-#fJ3') and post_date!='2017-01-02'

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "should" : [
            {"term" : {"postDate" : "2017-01-01"}},
            {"term" : {"articleID.keyword" : "XHDK-A-1293-#fJ3"}}
          ],
          "must_not" : {
            "term" : {"postDate" : "2017-01-02"}
          }
        }
      }
    }
  }
}

多条件查询二:select * from forum.article where article_id='XHDK-A-1293-#fJ3' or (article_id='JODL-X-1937-#pV7' and post_date='2017-01-01')

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "should" : [
            {
              "term" : {"articleID.keyword" : "XHDK-A-1293-#fJ3"}
            },
            {
              "bool" : {
                "must" : [
                  {"term" : {"articleID.keyword" : "JODL-X-1937-#pV7"}},
                  {"term" : {"postDate" : "2017-01-01"}}
                ]
              }
            }
          ]
        }   
      }
    }
  }
}

参考文献:https://www.jianshu.com/p/e1430282378d

免责声明:文章转载自《es使用term+filter查询(对type为text的查询注意点)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇cartographer参数调整flume拦截器下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java实现 http请求的同步和异步发送

http同步请求 一般使用httpClient实现 private void sendRequest() throws Exception{ String path ="/statistic/info"; CloseableHttpClient httpClient = HttpClients.createDefault(); /...

百度地图在项目中的使用(JS)

废话先: 这个项目是使用ASP.NET MVC 写的,而关于百度地图在项目中的应用不限于ASP.NET MVC 因为我大部分的API的使用是通过Javascript,想在项目中使用百度地图,你得先成为百度的开发者,具体的步骤,在本篇博文中不多叙述。 主题: 在使用百度地图的时候,你得先要获得一个ak 这里就是点击创建应用,它提供了几个类别1.for...

K8S系统学习(一)

参考链接:https://blog.csdn.net/HsiaChubby/article/details/90442170 参考链接:https://segmentfault.com/a/1190000018741112?utm_source=tag-newest 一、K8S架构图。(K8S的背景,作用什么的百度可以查阅,我主要一下跟实战相关的) 构成介...

在windows 7使用BCDEdit.exe修改启动菜单项

  最近重装了系统,电脑型号:Thinkpad R400 2784A74。原本想换个windows Server 2003的,可是没有与之对应的驱动程序,于是又换成windows 7 ultimate,考虑到之前使用的XP系统可能还会用到,于是想到做个双系统。   安装windows7的步骤简单说下:使用虚拟光驱+光盘镜像进行安装,过程是漫长的。此处略去1...

Java 基础(ASCII 码,Unicode 编码,UTF-8, 二进制)

ASCCII 码 在计算机内部,所有数据都使用二进制表示。每一个二进制位(bit)有0和1两种状态,因此8个二进制位就可以组合出256种状态,这被称为一个字节(byte)。一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000到11111111。 缺点: 不能表示所有字符。 相同的编码表示的字符不一样:比如...

Nginx使用Lua脚本加解密RSA字符串

本文主要介绍使用Lua脚本对采用RSA加密后的字符串进行解密的过程。 使用第三方类库lua-resty-rsa,参考地址:https://github.com/spacewander/lua-resty-rsa 下载并安装第三方依赖库 # Redis集群连接库依赖RSA加解密第三方依赖库[lua-resty-rsa],因此需要提前安装此第三方依赖库 #...