elasticsearch中DSL之Term level query(term query)

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

上例中addrtext属性,namekeyword属性;

  • 第一个查询是字段查询,搜索文本是zhongguo不会被分词(不会因为addr是text属性分词),所以要精确查询文档addr字段中是否存在zhongguo的文档。 因为文档中addr的值是zhongguo guangdong shenzhen,它会形成三个有效词zhongguoguangdongshenzhen,所以可以查到到结果。
  • 第二个查询是全文搜索,搜索文本是mahuateng,它会按照索引定义的name属性进行分词,因为namekeyword属性,所以不会被分词,要精确查询文档那么字段中是mahuateng的文档。
  • 第三个查询是全文搜索,搜索文本是zhongguo,它会按照索引定义的addr属性进行分词,因为addrtext属性,所以被分为zhongguo词元,因为文档中addr的值是zhongguo guangdong shenzhen,它会形成三个有效词zhongguoguangdongshenzhen,所以可以查到到结果。
  • 第四个查询返回为空,因为字段查询,搜索文本是zhongguo guangdong guangzhou不会被分词(不会因为addr是text属性分词),所以要精确查询文档addr字段中是否存在zhongguo guangdong guangzhou的文档。 因为文档中addr的值是zhongguo guangdong shenzhen,它会形成三个有效词zhongguoguangdongshenzhen,并没有zhongguo guangdong guangzhou这个词元,所以没有命中文档。
  • 第五个查询可以返回值,是全文搜索,搜索文本是zhangsan liszi,它会按照索引定义的name属性进行分词,因为namekeyword属性,所以不会被分词,要精确查询文档那么字段中是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索引中的文档。

返回的结果依次是:

"hits": [
    {
       "_index": "myindex",
       "_type": "mytype",
       "_id": "4",
       "_score": 1,
       "_source": {
          "name": "zhangqiang",
          "age": "32",
          "addr": "zhongguo sichuan chengdu say",
          "city": "chengdu"
       }
    },
    {
       "_index": "myindex",
       "_type": "mytype",
       "_id": "3",
       "_score": 1,
       "_source": {
          "name": "xiaoyu",
          "age": "30",
          "addr": "中国安徽亳州",
          "city": "shenzhen"
       }
    }
 ]

和 

"hits": [
   {
      "_index": "myindex",
      "_type": "mytype",
      "_id": "2",
      "_score": 1,
      "_source": {
         "name": "mahuateng",
         "age": "40",
         "addr": "zhongguo guangdong shenzhen",
         "city": "shenzhen"
      }
   },
   {
      "_index": "myindex",
      "_type": "mytype",
      "_id": "1",
      "_score": 1,
      "_source": {
         "name": "renzhenfei",
         "age": "71",
         "addr": "zhongguo guangdong guangzhou",
         "city": "guangzhou"
      }
   }
]

也可以自己查自己

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

通配符查询

  • * :匹配任意0个或多个字符
  • ?:匹配任意1个字符
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"]
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值