草庐IT

Elasticsearch 字段别名 field-alias

醉鱼! 2024-06-21 原文

环境

  • Elasticsearch 8.1
  • Kibana 8.1
  • MacOS 10.14.6

简介

首先我们还是先了解一下,什么是字段别名?大家可能听说过索引别名,通过索引的别名可以轻松的切换所需的数据来源与哪一个索引,那么什么是字段别名呢?所谓字段别名,就是索引mapping定义时的备用字段,通过字段别名可以替换搜索请求中的目标字段,字段别名可以用于搜索排序聚合高亮docvalue_fieldsstored_fieldssuggestions,下面我们一起来看一下字段别名的详细使用过程

使用

定义字段别名规范

  • 必须是一个明确的字段,不能是一个对象或者指向另一个字段别名
  • 在创建字段别名时,字段别名指向的目标字段必须已经存在
  • 如果定义了嵌套的对象,则字段别名必须具有同样的嵌套范围

字段别名只能指向一个字段,不能同时指向多个字段;

但是可以通过修改mapping中的字段别名设置指向另一个新字段

不支持使用字段别名的API

  • 首先是不能在写入数据的时候使用字段别名,因为本身字段别名是虚拟的,不存在的,所以不支持写入,同样也不能用于 copy_to
  • 因为字段的别名是不存在 _source中的,所以搜索请求时的过滤字段也是不会生效的

测试

  • 创建索引,定义字段别名

    其中创建了索引blog1blog2,各自定义了两个字段别名public_countpublic_content,在blog1索引中,public_count指向doc.count,public_content指向doc.content;在blog2索引中,public_count指向doc_count,public_content指向doc_content;

    PUT blog1
    {
      "mappings": {
        "properties": {
          "doc": {
            "properties": {
              "count": {
                "type": "long"
              },
              "content": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword"
                  }
                }
              }
            }
          },
          "creater": {
            "type": "keyword"
          },
          "public_count": {
            "type": "alias",
            "path": "doc.count"
          },
          "public_content": {
            "type": "alias",
            "path": "doc.content"
          }
        }
      }
    }
    
    
    PUT blog2
    {
      "mappings": {
        "properties": {
          "doc_count": {
            "type": "long"
          },
          "doc_content": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword"
              }
            }
          },
          "creater": {
            "type": "keyword"
          },
          "public_count": {
            "type": "alias",
            "path": "doc_count"
          },
          "public_content": {
            "type": "alias",
            "path": "doc_content"
          }
        }
      }
    }
    
  • 插入测试数据

    POST _bulk
    { "index":{"_index":"blog1","_id":"1"}}
    {"creater":"zuiyu1","doc.count":"100","doc.content":"zuiyu elasticsearch "}
    { "index":{"_index":"blog1","_id":"2"}}
    {"creater":"zuiyu2","doc.count":"200","doc.content":"zuiyu vue"}
    { "index":{"_index":"blog1","_id":"3"}}
    {"creater":"zuiyu3","doc.count":"300","doc.content":"java demo"}
    { "index":{"_index":"blog1","_id":"4"}}
    {"creater":"zuiyu4","doc.count":"300","doc.content":"java demo plus"}
    { "index":{"_index":"blog1","_id":"5"}}
    {"creater":"zuiyu5","doc.count":"300","doc.content":"java pro and elasticsearch"}
    { "index":{"_index":"blog2","_id":"1"}}
    {"creater":"zuiyu1","doc_count":"10","doc_content":"醉鱼ES小白入门课"}
    { "index":{"_index":"blog2","_id":"2"}}
    {"creater":"zuiyu2","doc_count":"550","doc_content":"醉鱼前端 vue 小白入门课"}
    { "index":{"_index":"blog2","_id":"3"}}
    {"creater":"zuiyu3","doc_count":"60","doc_content":"醉鱼java小白入门课"}
    { "index":{"_index":"blog2","_id":"4"}}
    {"creater":"zuiyu4","doc_count":"60","doc_content":"醉鱼MySQL8.0小白入门课"}
    { "index":{"_index":"blog2","_id":"5"}}
    {"creater":"zuiyu5","doc_count":"60","doc_content":"醉鱼Redis小白入门课"}
    
    
  • 搜索测试、聚合、排序、高亮、建议

    目标是实现搜索索引blog1blog2content内容中包含java的文档,因为两个索引的mapping结构完全不一样,所以使用定义的相同名称的public_countpublic_content

    • 聚合

      使用public_count字段搜索索引blog1blog2public_count 大于100的文档,对public_count进行聚合分桶

      GET blog*/_search?size=0
      {
        "query": {
          "range": {
            "public_count": {
              "gte": 100
              }
          }
        },
        "aggs": {
          "all_agg": {
            "terms": {
              "field": "public_count"
            }
          }
        }
      }
      
    • 排序

      使用public_count字段搜索索引blog1blog2public_count结果大于100的文档,对public_count进行降序输出

      GET blog*/_search
      {
        "query": {
          "range": {
            "public_count": {
              "gte": 100
              }
          }
        },
        "sort": [
          {
            "public_count": {
              "order": "desc"
            }
          }
        ]
      }
      
    • 高亮

      使用public_content字段搜索索引blog1blog2中包含java的,高亮输出,结果前后加上em标签

      GET blog*/_search
      {
        "query": {
          "wildcard": {
            "public_content": {
              "value": "*java*"
            }
          }
        },
        "highlight": {
          "fields": {
            "public_content": {
              "pre_tags": [
                "<em>"
              ],
              "post_tags": [
                "</em>"
              ]
            }
          }
        }
      }
      
    • 建议

      使用public_count字段搜索索引blog1blog2中搜索public_content中包含java的文档,输入一个错误单词jave,建议返回java

      GET blog*/_search
      {
        "query": {
          "wildcard": {
            "public_content": {
              "value": "*java*"
            }
          }
        },
        "suggest": {
          "YOUR_SUGGESTION": {
            "text": "jave",
            "term": {
              "field": "public_content"
            }
          }
        }
      }
      
    • _source测试

      使用_source测试返回字段public_countpublic_content,因为字段别名是虚拟的,所以此时是没有返回结果的

      GET blog*/_search
      {
        "query": {
          "wildcard": {
            "public_content": {
              "value": "*java*"
            }
          }
        },
        "_source": [
          "public_count",
          "public_content"
        ]
      }
      
    • 使用docvalue_fields请求字段获取

      GET blog*/_search
      {
        "query": {
          "wildcard": {
            "public_content": {
              "value": "*java*"
            }
          }
        },
         "docvalue_fields": [
          "public_count"
        ]
      }
      

使用场景

简单总结一下字段别名的使用场景:

  • 文中的例子,可以对同一个人在不同博客网站上写的内容进行统计
  • 获取采集的日志信息,不同的数据源,索引的日志mapping不一样,统计时就可以使用字段别名进行统一的统计

本文由 mdnice 多平台发布

有关Elasticsearch 字段别名 field-alias的更多相关文章

  1. ruby - capybara field.has_css?匹配器 - 2

    我在MiniTest::Spec和Capybara中使用以下规范:find_field('Email').must_have_css('[autofocus]')检查名为“电子邮件”的字段是否具有autofocus属性。doc说如下:has_css?(path,options={})ChecksifagivenCSSselectorisonthepageorcurrentnode.据我了解,字段“Email”是一个节点,因此调用must_have_css绝对有效!我做错了什么? 最佳答案 通过JonasNicklas得到了答案:No

  2. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  3. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  4. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  5. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  6. ruby-on-rails - 复数 for fields_for has_many 关联未显示在 View 中 - 2

    目前,Itembelongs_toCompany和has_manyItemVariants。我正在尝试使用嵌套的fields_for通过Item表单添加ItemVariant字段,但是使用:item_variants不显示该表单。只有当我使用单数时才会显示。我检查了我的关联,它们似乎是正确的,这可能与嵌套在公司下的项目有关,还是我遗漏了其他东西?提前致谢。注意:下面的代码片段中省略了不相关的代码。编辑:不知道这是否相关,但我正在使用CanCan进行身份验证。routes.rbresources:companiesdoresources:itemsenditem.rbclassItemi

  7. ruby-on-rails - Rails 单表继承 : How to override the value written to the type field - 2

    在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型

  8. ruby-on-rails - Sphinx - 何时对字段使用 'has' 和 'indexes' - 2

    我几天前在我的ruby​​onrails2.3.2上安装了Sphinx和Thinking-Sphinx,基本搜索效果很好。这意味着,没有任何条件。现在,我想用一些条件过滤搜索。我有公告模型,索引如下所示:define_indexdoindexestitle,:as=>:title,:sortable=>trueindexesdescription,:as=>:description,:sortable=>trueend也许我错了,但我注意到只有当我将:sortable=>true语法添加到这些属性时,我才能将它们用作搜索条件。否则它找不到任何东西。现在,我还在使用acts_as_tag

  9. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  10. ruby-on-rails - 如何为空白字段编写 rspec? [Rails3.1] - 2

    我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona

随机推荐