zoukankan      html  css  js  c++  java
  • ES elasticsearch searchtemplate查询模板

    定义一个Search template

    首先,我们来定义一个 search template 来看看它到底是什么东西。使用_scripts端点将模板存储在集群状态中。在 search template中使用的语言叫做 mustache。

    POST _scripts/my_search_template
    {
    "script": {
    "lang": "mustache",
    "source": {
    "query": {
    "match": {
    "{{my_field}}": "{{my_value}}"
    }
    }
    }
    }
    }
    在这里,我们定义了一个叫做 my_search_template 的 search template。如果我们想更新这个 search template,我们可以直接进行修改,然后再次运行上面的命令即可。

    在 match 的字段里,我们定义了两个参数:my_field 及 my_value。下面,我们来首先建立一个叫做 twitter 的数据库:

    PUT twitter/_doc/1
    {
    "user" : "双榆树-张三",
    "message" : "今儿天气不错啊,出去转转去",
    "uid" : 2,
    "age" : 20,
    "city" : "北京",
    "province" : "北京",
    "country" : "中国",
    "address" : "中国北京市海淀区",
    "location" : {
    "lat" : "39.970718",
    "lon" : "116.325747"
    }
    }

    PUT twitter/_doc/2
    {
    "user" : "虹桥-老吴",
    "message" : "好友来了都今天我生日,好友来了,什么 birthday happy 就成!",
    "uid" : 7,
    "age" : 90,
    "city" : "上海",
    "province" : "上海",
    "country" : "中国",
    "address" : "中国上海市闵行区",
    "location" : {
    "lat" : "31.175927",
    "lon" : "121.383328"
    }
    }
    我们这里把上面的两个文档存于到 twitter 的i ndex 之中。我们现在可以使用我们刚才定义的 search template 来进行搜索:

    GET twitter/_search/template
    {
    "id": "my_search_template",
    "params": {
    "my_field": "city",
    "my_value": "北京"
    }
    }
    显示的结果是:

    {
    "took" : 1,
    "timed_out" : false,
    "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
    },
    "hits" : {
    "total" : {
    "value" : 1,
    "relation" : "eq"
    },
    "max_score" : 0.9808292,
    "hits" : [
    {
    "_index" : "twitter",
    "_type" : "_doc",
    "_id" : "1",
    "_score" : 0.9808292,
    "_source" : {
    "user" : "双榆树-张三",
    "message" : "今儿天气不错啊,出去转转去",
    "uid" : 2,
    "age" : 20,
    "city" : "北京",
    "province" : "北京",
    "country" : "中国",
    "address" : "中国北京市海淀区",
    "location" : {
    "lat" : "39.970718",
    "lon" : "116.325747"
    }
    }
    }
    ]
    }
    }
    显示它只显示了我们的 city 为北京的一个文档,另外一个上海的文档没有做任何的显示。说明我们定义的 search template 是工作的。

    条件判断

    在 Mustache 语言中,它没有 if/else 这样的判断,但是你可以定 section 来跳过它如果那个变量是 false 还是没有被定义:

    {{#param1}}
    "This section is skipped if param1 is null or false"
    {{/param1}}
    我们定义如下的一个 search template:

    POST _scripts/docs_from_beijing_and_age
    {
    "script": {
    "lang": "mustache",
    "source":
    """
    {
    "query": {
    "bool": {
    "must": [
    {
    "match": {
    "city": "{{search_term}}"
    }
    }
    {{#search_age}}
    ,
    {
    "range": {
    "age": {
    "gte": {{search_age}}
    }
    }
    }
    {{/search_age}}
    ]
    }
    }
    }
    """
    }
    }
    在这里,我们同时定义了两个变量:search_term 及 search_age。针对 search_age,我们做了一个判断,如果它有定义,及做一个 range 的查询。如果没有定义,就只用 search_term。那么我们来做如下的实验:

    GET twitter/_search/template
    {
    "id": "docs_from_beijing_and_age",
    "params": {
    "search_term": "北京"
    }
    }
    显示的结果是:

    {
    "took" : 0,
    "timed_out" : false,
    "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
    },
    "hits" : {
    "total" : {
    "value" : 1,
    "relation" : "eq"
    },
    "max_score" : 0.9808292,
    "hits" : [
    {
    "_index" : "twitter",
    "_type" : "_doc",
    "_id" : "1",
    "_score" : 0.9808292,
    "_source" : {
    "user" : "双榆树-张三",
    "message" : "今儿天气不错啊,出去转转去",
    "uid" : 2,
    "age" : 20,
    "city" : "北京",
    "province" : "北京",
    "country" : "中国",
    "address" : "中国北京市海淀区",
    "location" : {
    "lat" : "39.970718",
    "lon" : "116.325747"
    }
    }
    }
    ]
    }
    }
    显然,city 为北京的文档已经被搜索到了。如果我们做如下的查询:

    GET twitter/_search/template
    {
    "id": "docs_from_beijing_and_age",
    "params": {
    "search_term": "北京",
    "search_age": "30"
    }
    }
    我们将搜索不到任何的结果,这是因为在这次查询中 search_age 已经被启用,而且在数据库中没有一个文档是来自“北京”,并且年龄大于 30 的。我们可以做如下的查询:

    GET twitter/_search/template
    {
    "id": "docs_from_beijing_and_age",
    "params": {
    "search_term": "北京",
    "search_age": "20"
    }
    }
    那么这次的显示结果为:

    {
    "took" : 0,
    "timed_out" : false,
    "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
    },
    "hits" : {
    "total" : {
    "value" : 1,
    "relation" : "eq"
    },
    "max_score" : 1.9808292,
    "hits" : [
    {
    "_index" : "twitter",
    "_type" : "_doc",
    "_id" : "1",
    "_score" : 1.9808292,
    "_source" : {
    "user" : "双榆树-张三",
    "message" : "今儿天气不错啊,出去转转去",
    "uid" : 2,
    "age" : 20,
    "city" : "北京",
    "province" : "北京",
    "country" : "中国",
    "address" : "中国北京市海淀区",
    "location" : {
    "lat" : "39.970718",
    "lon" : "116.325747"
    }
    }
    }
    ]
    }
    }
    显然这次我们搜索到我们想要的结果。

    查询 search template
    GET _scripts/<templateid>
    针对我们的情况:

    GET _scripts/docs_from_beijing_and_age
    显示的结果为:

    {
    "_id" : "docs_from_beijing_and_age",
    "found" : true,
    "script" : {
    "lang" : "mustache",
    "source" : """
    {
    "query": {
    "bool": {
    "must": [
    {
    "match": {
    "city": "{{search_term}}"
    }
    }
    {{#search_age}}
    ,
    {
    "range": {
    "age": {
    "gte": {{search_age}}
    }
    }
    }
    {{/search_age}}
    ]
    }
    }
    }
    """
    }
    }
    这个正是我们之前定义的一个 search template。

    删除一个 search template
    我们可以通过如下的命令来删除一个已经创建的 search template:

    DELETE _scripts/<templateid>
    验证 search template
    我们可以通过 _render 端点来验证我们的 search template。比如:

    GET _render/template
    {
    "source": """
    {
    "query": {
    "bool": {
    "must": [
    {
    "match": {
    "city": "{{search_term}}"
    }
    }
    {{#search_age}}
    ,
    {
    "range": {
    "age": {
    "gte": {{search_age}}
    }
    }
    }
    {{/search_age}}
    ]
    }
    }
    }
    """,
    "params": {
    "search_term": "北京",
    "search_age": "20"
    }
    }
    那么显示的结果是:

    {
    "template_output" : {
    "query" : {
    "bool" : {
    "must" : [
    {
    "match" : {
    "city" : "北京"
    }
    },
    {
    "range" : {
    "age" : {
    "gte" : 20
    }
    }
    }
    ]
    }
    }
    }
    }
    显然,这个就是我们想要的结果。
    原文链接:Elastic 中国社区官方博客

    螃蟹在剥我的壳,笔记本在写我,漫天的我落在枫叶上雪花上,而你在想我。 --章怀柔
  • 相关阅读:
    boost::asio在VS2008下的编译错误
    Java集合框架——接口
    ACM POJ 3981 字符串替换(简单题)
    ACM HDU 1042 N!(高精度计算阶乘)
    OneTwoThree (Uva)
    ACM POJ 3979 分数加减法(水题)
    ACM HDU 4004 The Frog's Games(2011ACM大连赛区第四题)
    Hexadecimal View (2011ACM亚洲大连赛区现场赛D题)
    ACM HDU 4002 Find the maximum(2011年大连赛区网络赛第二题)
    ACM HDU 4001 To Miss Our Children Time (2011ACM大连赛区网络赛)
  • 原文地址:https://www.cnblogs.com/lovezhr/p/15168948.html
Copyright © 2011-2022 走看看