ElasticSearch基本查询使用(2)

在介绍本章之前,需要先打开安装的Kibana页面, 并打开命令行工具页面:

并且根据上节的介绍,我们需要根据中文搜索,所以需要在建立映射时,指定中文字段的分词器为Ik分词器, 默认为英文分词器,每个中文一个词,需要重建索引,重建映射,首先用命令行执行如下命令:

# 删除索引
DELETE course
# 建立 course索引
PUT course

# 给course 指定映射, analyzer属性指定分词器
PUT course/_mapping
{
	"properties": {
		"name": {
			"type": "text",
			"analyzer":"ik_max_word"
		},
		"description": {
			"type": "text",
			"analyzer":"ik_max_word"
		},
		"studymodel": {
			"type": "keyword"
		}
	}
}

# 保存三个测试文档
POST /course/_doc
{
	"name": "Bootstrap开发框架",
	"description": "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
	"studymodel": "201001"
}
POST /course/_doc
{
	"name": "Java语言",
	"description": "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征",
	"studymodel": "201002"
}
POST /course/_doc
{
	"name": "Spring框架",
	"description": "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
	"studymodel": "201003"
}

1. 常用搜索入门

1.1 搜索全部

命令: GET course/_search

结果:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 1.0,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "P2xaGX0BjGPlWFrZF6_S",
        "_score" : 1.0,
        "_source" : {
          "name" : "Java语言",
          "description" : "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征",
          "studymodel" : "201002"
        }
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : 1.0,
        "_source" : {
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
          "studymodel" : "201003"
        }
      }
    ]
  }
}

返回结果包括了所有三个文档,放在数组 hits 中。一个搜索默认返回十条结果。

1.2 match 分词匹配搜索

领域特定语言 (DSL), 使用 JSON 构造了一个请求。我们可以像这样查询所有studymodel为 "201003"的文档:

GET course/_search
{
  "query": {
    "match": {
      "description": "框架"
    }
  }
}

结果:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.6502306,
    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 0.6502306,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : 0.43878573,
        "_source" : {
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
          "studymodel" : "201003"
        }
      }
    ]
  }
}

这个请求使用 JSON 构造,最外围包含了一个"query"属性,这是查询语句必须的

内部使用了一个 match 查询, 匹配了description 属性中带有"框架"二字的文档;

原理:

我们知道,在新增文档时,文本类型的字段会根据类型和分词类型进行拆分分词,并将拆出来的词语存到索引词库中,用于匹配,如果匹配到了,再查询此词语对应的文档,这也就是倒排索引

match查询会首先分析查询条件,先将查询条件进行分词(使用和字段一样的分词器,也可以自己指定),然后再查询

在本例中,搜索词为"框架",分出的词也是框架二字;所以查询到了文档中description 字段带有"框架"二字的文档

匹配多个词语:

GET course/_search
{
  "query": {
    "match": {
      "description": "框架界面"
    }
  }
}

可以看到,这次搜索的词语,不再是单个词语,而是由"框架" 和 "界面" 两词组成,而搜索时,也会将此搜索语句拆分成这两个词,进行匹配:

结果:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.6398609,
    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 1.6398609,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : 0.43878573,
        "_source" : {
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
          "studymodel" : "201003"
        }
      }
    ]
  }
}

从结果中可以看到, 两个文档中都有"框架" 这个词语, 但是只有一个有"界面"这个 词语, 所以可以判断,词语匹配是或者的关系,只要有一个匹配上即可, 但是根据匹配度,匹配度高的排在前面;而一个词语都没有匹配上的则没有被查询出来;

1.2.1 operator 属性

上面的分词匹配中,我们发现只要文档中匹配到分词中的其中一个词语就算是匹配上了

这是因为默认的match匹配的operator 属性为 or ,即为或者的关系,也可以修改为and 即,每个词语都必须匹配上:

GET course/_search
{
	"query": {
		"match": {
			"description": {
				"query": "框架界面",
				"operator": "and"
			}
		}
	}
}

结果:

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.6398609,
    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 1.6398609,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      }
    ]
  }
}

同样是搜索这个词语,但是匹配到结果就只有这一个每个词语都匹配上的文档

1.2.2 minimum_should_match 属性

上边使用的operator = or表示只要有一个词匹配上就得分,如果实现三个词至少有两个词匹配如何实现?

使用minimum_should_match可以指定文档匹配词的占比

比如搜索语句如下:

GET course/_search
{
  "query": {
    "match": {
      "description": {
      "query": "推出框架界面",
      "operator": "or",
      "minimum_should_match": "80%"
      }
    }
  }
}

结果:

  "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 2.629491,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      }
    ]

“推出框架界面”会被分为三个词:推出、框架、界面

设置"minimum_should_match": "80%"表示,三个词在文档的匹配占比为80%,即3*0.8=2.4,向下取整得2,表

示至少有两个词在文档中要匹配成功。

1.3 multi Query 匹配多字段

上边学习的matchQuery 一次只能匹配一个Field,本节学习multiQuery,一次可以匹配多个字段。

GET course/_search
{
  "query": {
    "multi_match": {
      "query": "推出框架界面",
      "fields":["name","description"],
      "operator": "or",
      "minimum_should_match": "50%"
    }
  }
}

指定匹配name, 和description 两个字段, 定义的 operatorminimum_should_match 属性会作用于每个字段的匹配, 只要有一个字段符合条件,则整个表达式成立:

结果:

"hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 2.629491,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : 0.49917626,
        "_source" : {
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
          "studymodel" : "201003"
        }
      }
    ]

结果查询了两个结果,

第一个结果的 namedescription 属性都符合 50% 的匹配条件.

第二个结果的 name 属性匹配上"框架字符",50%,向下取整也就是一个词,也算匹配上

1.4 term 精确匹配搜索

Term Query为精确查询,在搜索时会整体匹配关键字,不再将关键字分词。

同样,我们使用 term语句查询 "框架界面" 二字, 将不再匹配到任何文档:

GET course/_search
{
  "query": {
    "term": {
      "description": "框架界面"
    }
  }
}

结果:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

这就是因为,在使用term搜索时,将不会再对搜索词进行分词,而是进行精确匹配,而原文并没有将 "框架界面"分成一个单独的词语放进索引库中.

所以一般使用term查询,都是为了精确查询,例如:

GET course/_search
{
  "query": {
    "term": {
      "studymodel": "201003"
    }
  }
}

查询编号为2001003的课程,结果:

 "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.9808291,
    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : 0.9808291,
        "_source" : {
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
          "studymodel" : "201003"
        }
      }
    ]

或者可以使用terms ,匹配多个

GET course/_search
{
  "query": {
    "terms": {
      "studymodel": ["201003","201001"]
    }
  }
}

结果:


    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 1.0,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : 1.0,
        "_source" : {
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
          "studymodel" : "201003"
        }
      }
    ]

1.4 模糊匹配

wildcard 通配符查询也是一种底层基于词的查询,它使用标准的 shell 通配符查询: ? 匹配任意字符, * 匹配 0 或多个字符。类似 SQL中的like查询

GET course/_search
{
  "query": {
    "wildcard": {
      "studymodel": "201*"
    }
  }
}

查询所有编号以"201" 开头的课程,结果将查询出全部:

    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 1.0,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "P2xaGX0BjGPlWFrZF6_S",
        "_score" : 1.0,
        "_source" : {
          "name" : "Java语言",
          "description" : "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征",
          "studymodel" : "201002"
        }
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : 1.0,
        "_source" : {
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
          "studymodel" : "201003"
        }
      }
    ]

如果有更加复杂的模糊匹配需求,也可以使用正则匹配的方式:

GET course/_search
{
  "query": {
    "regexp": {
      "studymodel": "201[0-9].3+"
    }
  }
}

匹配以201开头,尾号是3,并且全由数字组成的编号课程,查询结果如下:

    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : 1.0,
        "_source" : {
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
          "studymodel" : "201003"
        }
      }
    ]

注意:

wildcardregexp 查询的工作方式需要扫描倒排索引中的词列表才能找到所有匹配的词,然后依次获取每个词相关的文档 ID ,相对比较耗费资源和时间

这也意味着需要同样注意前缀查询存在的问题,对有很多唯一词的字段执行这些查询可能会消耗非常多的资源,所以要避免使用左通配这样的模式匹配(如: *foo.*foo 这样的正则式)

wildcardregexp 查询是基于词操作的,如果用它们来查询 analyzed 字段,它们会检查字段里面的每个词,而不是将字段作为整体来处理。

比方说包含 “Quick brown fox” 的 title 字段会生成词: quickbrownfox

会匹配以下这个查询:

{ "regexp": { "title": "br.*" }}

但是不会匹配以下两个查询:

{ "regexp": { "title": "Qu.*" }} 
{ "regexp": { "title": "quick br*" }} 

在索引里的词是 quick 而不是 Quick

quickbrown 在词表中是分开的。

1.5 布尔查询

布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。类似SQL中的 or 或者 and

三个参数:

​ must:文档必须匹配must所包括的查询条件,相当于 “AND”

​ should:文档应该匹配should所包括的查询条件其当于 "OR"

​ must_not:文档不能匹配must_not所包括的该查询条件,相当于“NOT”

分别使用 must、should、must_not测试下边的查询:

1.5.1 must

GET course/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "description": "程序"
          }
        },
        {
          "match": {
            "name": "框架"
          }
        }
      ]
    }
  }
}

如表达式所示, 使用了bool 表达式包含了两个match查询(子查询类型无所谓,bool查询只是对各个结果取最终结果)

需要同时满足 descriptionname 字段都匹配上对应的字符

结果只有一条满足:

    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 1.777754,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      }
    ]

1.5.2: should

GET course/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "description": "程序"
          }
        },
        {
          "match": {
            "name": "框架"
          }
        }
      ]
    }
  }
}

两个表达式,只要一个满足即可

结果匹配了两个满足条件的:

    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 1.777754,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : 0.49917626,
        "_source" : {
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
          "studymodel" : "201003"
        }
      }
    ]

同时这里也可以使用"minimum_should_match" 属性,来自定义需要匹配的条数,默认相当于1, 即表达式中满足一条结果即可,如果设置为2,则代表都需满足,和must相当:

GET course/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "description": "程序"
          }
        },
        {
          "match": {
            "name": "框架"
          }
        }
      ]
       , "minimum_should_match": 2
    }
  }
}

结果:

    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 1.777754,
        "_source" : {
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
          "studymodel" : "201001"
        }
      }
    ]

1.5.3 must_not

相当于should 表达式的取反,即表达式一个都不能匹配上:

GET course/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "description": "程序"
          }
        },
        {
          "match": {
            "name": "框架"
          }
        }
      ]
    }
  }
}

结果为name不包含程序二字的并且描述中不包含框架二字的:

"hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "P2xaGX0BjGPlWFrZF6_S",
        "_score" : 0.0,
        "_source" : {
          "name" : "Java语言",
          "description" : "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征",
          "studymodel" : "201002"
        }
      }
    ]

1.6 范围查询

在介绍后面之前,需要添加一个数值类型的价格字段,执行如下命令:

# 添加字段,指定类型为float
PUT course/_mapping
{
	"properties": {
		"price": {
			"type": "float"
		}
	}
}
#根据编号修改价格:
POST course/_update_by_query
{
   "script": {
    "source": "ctx._source['price']=10.5;"
  },
  "query":{
    "term": {
      "studymodel": {
        "value": "201001"
      }
    }
  }
}

POST course/_update_by_query
{
   "script": {
    "source": "ctx._source['price']=5.6;"
  },
  "query":{
    "term": {
      "studymodel": {
        "value": "201002"
      }
    }
  }
}

POST course/_update_by_query
{
   "script": {
    "source": "ctx._source['price']=20.3;"
  },
  "query":{
    "term": {
      "studymodel": {
        "value": "201003"
      }
    }
  }
}

对于数字,除了精确值查询。实际上,对进行过滤有时会更有用。例如,我们可能想要查找所有价格大于 10 且小于 20 元的课程。可以使用 range查询:

GET course/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 10,
        "lte": 20
      }
    }
  }
}

查询结果:

    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 1.0,
        "_source" : {
          "price" : 10.5,
          "studymodel" : "201001",
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果"
        }
      }
    ]

range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项如下:

  • gt: > 大于(greater than)
  • lt: < 小于(less than)
  • gte: >= 大于或等于(greater than or equal to)
  • lte: <= 小于或等于(less than or equal to)

2. 排序

在使用query关键字搜索时,默认按照每个文档的得分,也就是文档对于搜索条件的匹配度进行排序(_score字段)

也可以指定结果排序,这样在查询时,将不会进行计算得分

下面根据价格查询5~30的课程,并按价格降序

GET course/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 5,
        "lte": 30
      }
    }
  }
  , "sort": [
    {
      "price": {
        "order": "asc"
      }
    }
  ]
}

结果:

    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "P2xaGX0BjGPlWFrZF6_S",
        "_score" : null,
        "_source" : {
          "price" : 5.6,
          "studymodel" : "201002",
          "name" : "Java语言",
          "description" : "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征"
        },
        "sort" : [
          5.6
        ]
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : null,
        "_source" : {
          "price" : 10.5,
          "studymodel" : "201001",
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果"
        },
        "sort" : [
          10.5
        ]
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : null,
        "_source" : {
          "price" : 20.3,
          "studymodel" : "201003",
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益"
        },
        "sort" : [
          20.3
        ]
      }
    ]

如果需要按照多个字段排序,类似mysql, 也可以指定多个字段,如果第一个字段相同,则按第二个字段排序:

GET course/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 5,
        "lte": 30
      }
    }
  }
  , "sort": [
    {
      "price": {
        "order": "asc"
      }
    },
    {
      "studymodel": {
        "order": "asc"
      }
    }
  ]
}

3. 分页

ES支持分页查询,传入两个参数:from和size。和mysql中的limit 两个参数相同

form:表示起始文档的下标,从0开始。

size:查询的文档数量。

下面排序后,从下标1开始查询,查询两个


GET course/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 5,
        "lte": 30
      }
    }
  },
  "from":1,
  "size":2
  , "sort": [
    {
      "price": {
        "order": "asc"
      }
    },
    {
      "studymodel": {
        "order": "asc"
      }
    }
  ]
}

结果并没有显示第一条价格最低的商品

  "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : null,
        "_source" : {
          "price" : 10.5,
          "studymodel" : "201001",
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果"
        },
        "sort" : [
          10.5,
          "201001"
        ]
      },
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "QGxjGX0BjGPlWFrZka88",
        "_score" : null,
        "_source" : {
          "price" : 20.3,
          "studymodel" : "201003",
          "name" : "Spring框架",
          "description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益"
        },
        "sort" : [
          20.3,
          "201003"
        ]
      }
    ]

4. 过滤器(filter)

Elasticsearch 使用的查询语言(DSL)拥有一套查询组件,这些组件可以以无限组合的方式进行搭配。

这套组件可以在以下两种情况下使用:过滤情况(filtering context)和查询情况(query context)。

当使用于 过滤情况(filter) 时,查询被设置成一个“不评分”或者“过滤”查询。即,这个查询只是简单的问一个问题:“这篇文档是否匹配?”。回答也是非常的简单,yes 或者 no ,二者必居其一。

  • created 时间是否在 20132014 这个区间?
  • status 字段是否包含 published 这个单词?
  • lat_lon 字段表示的位置是否在指定点的 10km 范围内?

当使用于 查询情况(query) 时,查询就变成了一个“评分”的查询。和不评分的查询类似,也要去判断这个文档是否匹配,同时它还需要判断这个文档匹配的有 多好(匹配程度如何)。 此查询的典型用法是用于查找以下文档:

  • 查找与 full text search 这个词语最佳匹配的文档
  • 包含 run 这个词,也能匹配 runsrunningjog 或者 sprint
  • 包含 quickbrownfox 这几个词 — 词之间离的越近,文档相关性越高
  • 标有 lucenesearch 或者 java 标签 — 标签越多,相关性越高

性能差异:

过滤查询(filter)只是简单的检查包含或者排除,这就使得计算起来非常快。并且结果会被缓存到内存中

以便快速读取,所以有各种各样的手段来优化查询结果。

相反,评分查询(query)不仅仅要找出匹配的文档,还要计算每个匹配文档的相关性,计算相关性使得它们比不评分查询费力的多。同时,查询结果并不缓存。

多亏倒排索引,一个简单的评分查询在匹配少量文档时可能与一个涵盖百万文档的filter表现的一样好,甚至会更好。但是在一般情况下,一个filter 会比一个评分的query性能更优异,并且每次都表现的很稳定。

通常的规则是,使用查询(query)语句来进行 全文 搜索或者其它任何需要影响 相关性得分 的搜索。除此以外的情况都使用过滤(filters)。

使用:

自 Elasticsearch 问世以来,查询与过滤(queries and filters)就独自成为 Elasticsearch 的组件。

但从 Elasticsearch 2.0 开始,过滤(filters)已经从技术上被排除了, 我们上面所有的查询也是基于query关键字,进行查询, 但是,在bool查询中,我们可以使用 除了must,shuold,must_not 之外的属性filter,来实现

如下例, 匹配description 字段,并且使用过滤(filter)的方式再匹配studymodel和price 字段,其中filter的含义和must相同,代表filter里的所有条件都需要满足

GET course/_search
{
	"query": {
		"bool": {
			"must": [{
				"match": {
					"description": {
						"query": "框架"
					}
				}
			}],
			"filter": [{
					"term": {
						"studymodel": "201001"
					}
				},
				{
					"range": {
						"price": {
							"gte": 5,
							"lte": 20
						}
					}
				}
			]
		}

	}
}

结果:

    "hits" : [
      {
        "_index" : "course",
        "_type" : "_doc",
        "_id" : "PmxaGX0BjGPlWFrZEK_N",
        "_score" : 0.6502306,
        "_source" : {
          "price" : 10.5,
          "studymodel" : "201001",
          "name" : "Bootstrap开发框架",
          "description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果"
        }
      }
    ]
原文地址:https://www.cnblogs.com/xjwhaha/p/15594990.html