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

插入测试数据

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
    }
  ]
}

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

原文地址:https://www.cnblogs.com/parent-absent-son/p/11063765.html

时间: 2024-10-11 06:38:09

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

mongodb 模糊查询以及$type使用

mongodb 模糊查询以及$type使用 2012-09-11 14:13:30|  分类: mongodb |  标签: |举报 |字号大中小 订阅 最近有一监控业务,由于数据采集到非数字内容,导致监控图表无法正常显示,所以要找出这部分数据,进行删除,然后开发员从源头更正插入数据库的数据,不再产生非数字内容. 下面举一个例子: 建立测试数据: for(i=1;i<=100;i++){db.test.insert({id:i,content:"test content",nam

[Elasticsearch] 控制相关度 (三) - 通过查询结构调整相关度以及boosting查询

本章翻译自Elasticsearch官方指南的Controlling Relevance一章. 通过查询结构调整相关度 ES提供的查询DSL是相当灵活的.你可以通过将单独的查询子句在查询层次中上下移动来让它更重要/更不重要.比如,下面的查询: quick OR brown OR red OR fox 我们可以使用一个bool查询,对所有词条一视同仁: GET /_search { "query": { "bool": { "should": [

Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询

原文:Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询 如果允许在UI层直接访问Linq to Sql的DataContext,可以省去很多问题,譬如在处理多表join的时候,我们使用var来定义L2S查询,让编译器自动推断变量的具体类型(IQueryable<匿名类型>),并提供友好的智能提示:而且可以充分应用L2S的延迟加载特性,来进行动态查询.但如果我们希望将业务逻辑放在一个独立的层中(譬如封装在远程的WCF应用中),又希望在逻辑层应用Linq to sql,则情

自动生成 Lambda查询和排序,从些查询列表so easy

如下图查询页面,跟据不同条件动态生成lambda的Where条件和OrderBy,如果要增加或调整查询,只用改前台HTML即可,不用改后台代码 前台代码: 1 <div style="padding-bottom: 5px;" id="queryForm"> 2 3 <span>员工姓名:</span><input type="text" emptytext="ddd" data-op

数据的查询(一)——单条件查询

数据的查询分为但条件查询和多条件查询 在查询之前,将查询数据库进行封装 <?php class DBDA { public $host="localhost"; //数据库地址 public $uid = "root"; //数据库用户名 public $pwd = ""; //密码 //执行sql语句,返回相应的结果 //参数:$sql代表执行的sql语句:$type是sql语句类型0代表查询,1代表其他:$db代表操作的数据库 publ

使用resultMap定义查询结果集,实现关联查询

接下来介绍resultMap定义查询结果集,实现关联查询 1 首先在接口中定义操作的方法 public interface EmployeeMapperPlus { public Employee getEmpAndDept(Integer id); } 2在xml里进行配置 <!--第一种进行配置 联合查询:级联属性封装结果集 --> <resultMap type="com.atguigu.mybatis.bean.Employee" id="MyDif

Django:表多对多查询、聚合分组、FQ查询、事务

1表多对多的关系查询 准备工作创建表结构 from django.db import models # Create your models here. class Publisher(models.Model): name = models.CharField(max_length=32, verbose_name="名称") def __str__(self): return self.name class Book(models.Model): title = models.Ch

表连接查询与where后使用子查询的性能分析。

子查询就是在一条查询语句中还有其它的查询语句,主查询得到的结果依赖于子查询的结果. 子查询的子语句可以在一条sql语句的FROM,JOIN,和WHERE后面,本文主要针对在WHERE后面使用子查询与表连接查询的性能做出一点分析. 对于表连接查询和子查询性能的讨论众说纷纭,普遍认为的是表连接查询的性能要高于子查询.本文将从实验的角度,对这两种查询的性能做出验证,并就实验结果分析两种查询手段的执行流程对性能的影响. 首先准备两张表 1,访问日志表mm_log有150829条记录(相关sql文件已放在

QBC查询、离线条件查询(DetachedCriteric)和分页查询模版

一.QBC检索步骤 QBC检索步骤: 1.调用Session的createCriteria()方法创建一个Criteria对象. 2.设定查询条件.Expression类提供了一系列用于设定查询条件的静态方法, 这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件. Criteria的add()方法用于加入查询条件. 3.调用Criteria的list()方法执行查询语句.该方法返回List类型的查询结果,在 List集合中存放了符合查询条件的持久化对象. 比较运