Term Level Query
这里翻译为字段查询,字段查询是查询的文本不会被分词,只有对应的文档精确存在对应的查询文本才会返回。
可以发现,字段查询是指查询文本不会被分词,而不是索引对应的mapping该字段不能分词,即使对应的字段是text属性,只要该文档的字段中存在对应的词元,就会返回。 一般如果没有指定查询文本的分词器,就会使用mapping定义该字段的分词器来分析查询文本,所以一般我们用字段查询都是查询mapping中字段属性为keyword的字段。但是这不意味着match不能搜索keyword定义的字段,也不能说字段查询不能搜索text定义的字段。只要文档中包含查询文本有效的词元都会返回。
索引的mapping
"myindex": {
"aliases": {},
"mappings": {
"mytype": {
"properties": {
"addr": {
"type": "text"
},
"age": {
"type": "integer"
},
"city": {
"type": "keyword"
},
"content": {
"type": "text"
},
"name": {
"type": "keyword"
}
}
}
}
查询1
GET myindex/_search
{
"query": {
"term": {
"addr" : "zhongguo"
}
}
}
查询2
GET myindex/_search
{
"query": {
"match": {
"name" : "mahuateng"
}
}
}
查询3
GET myindex/_search
{
"query": {
"match": {
"addr" : "zhongguo"
}
}
}
都可以返回结果:
"hits": [
{
"_index": "myindex",
"_type": "mytype",
"_id": "2",
"_score": 0.6931472,
"_source": {
"name": "mahuateng",
"age": "40",
"addr": "zhongguo guangdong shenzhen",
"city": "shenzhen"
}
}
]
查询4
GET myindex/_search
{
"query": {
"term": {
"addr" : "zhongguo guangdong guangzhou"
}
}
}
查询5
GET myindex/_search
{
"query": {
"match": {
"name" : "zhangsan lisi"
}
}
}
返回结果:
{
"_index": "myindex",
"_type": "mytype",
"_id": "5",
"_score": 0.2876821,
"_source": {
"name": "zhangsan lisi",
"age": "71",
"addr": "zhongguo guangdong guangzhou",
"city": "guangzhou"
}
}
上例中addr 是text 属性,name 是keyword 属性;
- 第一个查询是字段查询,搜索文本是
zhongguo ,不会被分词(不会因为addr是text属性分词),所以要精确查询文档addr字段中是否存在zhongguo 的文档。 因为文档中addr 的值是zhongguo guangdong shenzhen ,它会形成三个有效词zhongguo 、guangdong 、shenzhen ,所以可以查到到结果。 - 第二个查询是全文搜索,搜索文本是
mahuateng ,它会按照索引定义的name 属性进行分词,因为name 是keyword 属性,所以不会被分词,要精确查询文档那么字段中是mahuateng 的文档。 - 第三个查询是全文搜索,搜索文本是
zhongguo ,它会按照索引定义的addr 属性进行分词,因为addr 是text 属性,所以被分为zhongguo 词元,因为文档中addr 的值是zhongguo guangdong shenzhen ,它会形成三个有效词zhongguo 、guangdong 、shenzhen ,所以可以查到到结果。 - 第四个查询返回为空,因为字段查询,搜索文本是
zhongguo guangdong guangzhou ,不会被分词(不会因为addr是text属性分词),所以要精确查询文档addr 字段中是否存在zhongguo guangdong guangzhou 的文档。 因为文档中addr的值是zhongguo guangdong shenzhen ,它会形成三个有效词zhongguo 、guangdong 、shenzhen ,并没有zhongguo guangdong guangzhou 这个词元,所以没有命中文档。 - 第五个查询可以返回值,是全文搜索,搜索文本是
zhangsan liszi ,它会按照索引定义的name 属性进行分词,因为name 是keyword 属性,所以不会被分词,要精确查询文档那么字段中是zhangsan lisi 的文档。(而不是只要只要含有zhangsan ,lisi 其中一个词元就会返回,这个容易误解)
1、所以我们通常在使用的时候,字段查询通常作用于属性定义为keyword 的字段。全文搜索通常作用于定义为text 的字段。 2、 字段查询也可以作用于text 的字段。只要文档中精确存在查询文本的对应的词元就会返回 3、全文搜索也可以作用于keyword 字段,只是查询文本不会被分词,要精确配置才会返回。 4、字段查询决定查询文本不能分词,只要文档中精确存在对应的词元就会返回;全文搜索要分词,但是要按照规则分词(一般都是按照文档定义的mapping分词器分词),只要文档中存在分词后任何一个有效词元都会返回。
1.Term Query
单个字段查询:
GET myindex/_search
{
"query": {
"term": {
"name" : "mahuateng"
}
}
}
精确查找name 的反向索引中有mahuateng 的文档。
2.Terms Query
多字段值精确查询
GET myindex/_search
{
"query": {
"terms": {
"name": [
"mahuateng",
"renzhenfei"
]
}
}
}
返回结果:
"hits": [
{
"_index": "myindex",
"_type": "mytype",
"_id": "2",
"_score": 0.9808292,
"_source": {
"name": "mahuateng",
"age": "40",
"addr": "zhongguo guangdong shenzhen",
"city": "shenzhen"
}
},
{
"_index": "myindex",
"_type": "mytype",
"_id": "1",
"_score": 0.2876821,
"_source": {
"name": "renzhenfei",
"age": "71",
"addr": "zhongguo guangdong guangzhou",
"city": "guangzhou"
}
}
]
- terms lookup mechanism:相当于sql中的级联查询(可以跨索引,也可以自己查自己)
支持的参数: 1.index :子查询的索引(与查询相同,可以省略) 2.type:子查询的类型 3.id:子查询的文档的id(其实内部是_id) 4.path:查询的字段 5.routing:可以自定义路由
从上可以发现,只能从id指定,这样的话,其实意义不大。
举个栗子:
定义一个索引
PUT my_other_index
{
"mappings": {
"mytype": {
"properties": {
"attr1" : {
"type": "keyword"
},
"attr2" : {
"properties": {
"attr2_in" :{
"type": "keyword"
}
}
}
}
}
}
}
写入数据:
POST my_other_index/mytype/1
{
"attr1" :[ "1", "2"],
"attr2" :{
"attr2_in" : ["3", "4"]
}
}
展示:
"hits": [
{
"_index": "my_other_index",
"_type": "mytype",
"_id": "1",
"_score": 0.2876821,
"_source": {
"attr1": [
"1",
"2"
],
"attr2": {
"attr2_in": [
"3",
"4"
]
}
}
}
]
现在我们使用级联查询(可以跨索
GET myindex/_search
{
"query": {
"terms": {
"_id": {
"index" : "my_other_index",
"type" : "mytype",
"id" : "1",
"path" : "attr2.attr2_in"
}
}
}
}
和
GET myindex/_search
{
"query": {
"terms": {
"_id": {
"index" : "my_other_index",
"type" : "mytype",
"id" : "1",
"path" : "attr1"
}
}
}
}
都可以返回myindex索引中的文档。
也可以自己查自己
GET myindex/_search
{
"query": {
"terms": {
"age": {
"index" : "myindex",
"type" : "mytype",
"id" : "1",
"path" : "age"
}
}
}
}
含义是查找与文档1相同年龄的人。
3.Range Query
范围查询
- gte:大于等于
- gt:大于
- lte:小于等于
- lt:小于
GET myindex/_search
{
"query": {
"range": {
"age": {
"gt" : 20
}
}
}
}
4.Exists Query
字段存在非空值(空值是:null、[]、 [null] ),""不是空值。
GET myindex/_search
{
"query": {
"exists" :{
"field" : "name"
}
}
}
字段是空值
GET myindex/_search
{
"query": {
"bool": {
"must_not": [
{
"exists" :{
"field" : "name"
}
}
]
}
}
}
5.Prefix Query
前缀查询
GET myindex/_search
{
"query": {
"prefix": {
"name": {
"value": "ma"
}
}
}
}
6.Wildcard Query
通配符查询
GET myindex/_search
{
"query": {
"wildcard": {
"name": {
"value": "ma*hua?*"
}
}
}
}
1.不要使用* 或者? 开头查询,因为这样会导致特别慢。 2.本身通配符查询效率也不高。
7.Regexp Query
正则表达是查询
GET /_search
{
"query": {
"regexp":{
"name.first": "s.*y"
}
}
}
和通配符?作用不同 通配符?是必须是一个字符 正则是前面的字符出现0次或1次 同样正则表达式可能效率很低
8.Fuzzy Query
模糊查询:和全文搜索参数是一致的。(编辑距离算法)
GET /_search
{
"query": {
"fuzzy" : {
"user" : {
"value" : "ki",
"boost" : 1.0,
"fuzziness" : 2,
"prefix_length" : 0,
"max_expansions": 100
}
}
}
}
9.Ids Query
按照id查询
GET myindex/_search
{
"query": {
"ids": {
"values": "1"
}
}
}
GET myindex/_search
{
"query": {
"ids": {
"values": ["1", "2"]
}
}
}
|