当前位置:首页 > 技术 > 正文内容

使用Java进行Elasticsearch索引管理

访客 技术 2026年6月5日 1

索引创建

/**
 * 创建新索引
 * */
@Test
public void establishNewIndex(){
    // 创建索引
    CreateIndexResponse response = esClient.admin().indices().prepareCreate("product_index").get();
    System.out.println(response.toString());

}

默认情况下创建的索引没有映射配置

索引删除

/**
 * 删除指定索引
 * */
@Test
public void removeIndex(){
    // 删除索引
    esClient.admin().indices().prepareDelete("product_index").get();
}

索引映射配置

为什么需要手动定义映射?

在实际应用中,经常会出现数据精度丢失的问题,这通常是由于没有正确设置索引映射或完全没有进行映射配置导致的<br></br>Elasticsearch初次索引文档X时,其中的某个字段是整数类型;通过自动类型检测,系统将其设置为整型(integer);<br></br>随后在索引另一个文档Y时,Y文档在同一字段中存储了浮点型数值;此时elasticsearch会自动截断小数部分,仅保留整数部分;<br></br>这会导致数据不准确!<br></br>​

如果你熟悉SQL数据库,应该知道在存储数据前需要创建模式来描述数据结构;尽管elasticsearch是一个无模式的搜索引擎,可以自动推断数据结构;

但我们仍然认为由自己控制并明确定义数据结构更为合理;在实际生产环境中,我们通常也会手动创建映射;

注意:创建映射时,索引必须已存在

{
"settings":{
   "shards":3,
   "replicas":1
},
"mappings":{
   "product_info":{
       "dynamic":"strict",
       "properties":{
           "productId":{"type": "string", "store": true},
           "productName":{"type": "string","store": true,"index" : "analyzed","analyzer": "ik_max_word"},
           "category":{"type": "string","store": true},
           "price":{"type": "double","store": true},
           "publishDate":{"type": "date","store": true},
           "manufacturer":{"type": "string","store": true},
           "description":{"type": "string","store": true,"index" : "analyzed","analyzer": "ik_max_word"},
           "inStock": {"type": "boolean", "index": "not_analyzed"}
       }
    }
}

1):创建索引基础结构

/**<br></br> * 创建新索引<br></br> * */<br></br>@Test<br></br>public void setupIndex(){<br></br>    <br></br>    CreateIndexResponse result = esClient.admin().indices().prepareCreate("book_catalog").get();<br></br>    System.out.println(result.toString());<br></br>​<br></br>}<br></br>​<br></br>​

2):通过代码配置索引映射(包含错误处理)

/**<br></br> * 索引映射配置类<br></br> */<br></br>public class IndexMappingConfig {<br></br>    public static void configureMapping() throws UnknownHostException {<br></br>        TransportClient client = null;<br></br>        Map<String, Integer> shardConfig = new HashMap<String, Integer>();<br></br>        shardConfig.put("number_of_shards", 3);<br></br>        shardConfig.put("number_of_replicas", 1);<br></br>        Settings settings = Settings.builder()<br></br>                .put("cluster.name", "production_cluster")<br></br>                .build();<br></br>        client = new PreBuiltTransportClient(settings)<br></br>                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node01"), 9300));<br></br>        System.out.println("========集群连接成功=============");<br></br>​<br></br>​<br></br>        XContentBuilder mappingBuilder = null;<br></br>        try {<br></br>            mappingBuilder = jsonBuilder()<br></br>                    .startObject()<br></br>                    .startObject("book_info").field("dynamic", "true")<br></br>                    .startObject("properties")<br></br>                    .startObject("isbn").field("type", "string").field("store", "yes").endObject()<br></br>                    .startObject("title").field("type", "string").field("store", "yes").field("analyzer", "ik_max_word").endObject()<br></br>                    .startObject("author").field("type", "string").field("store", "yes").endObject()<br></br>                    .startObject("price").field("type", "double").field("store", "yes").endObject()<br></br>                    .startObject("publishDate").field("type", "date").field("store", "yes").endObject()<br></br>                    .startObject("publisher").field("type", "string").field("store", "yes").endObject()<br></br>                    .startObject("summary").field("type", "string").field("store", "yes").field("analyzer", "ik_max_word").endObject()<br></br>                    .startObject("available").field("type", "boolean").field("store", "yes").field("index", "not_analyzed").endObject()<br></br>                    .endObject()<br></br>                    .endObject()<br></br>                    .endObject();<br></br>            PutMappingRequest mappingRequest = Requests.putMappingRequest("book_catalog")<br></br>                    .type("book_info")<br></br>                    .source(mappingBuilder);<br></br>            UpdateSettingsRequest settingsRequest = new UpdateSettingsRequest();<br></br>            settingsRequest.settings(shardConfig);<br></br>            client.admin().indices().updateSettings(settingsRequest).actionGet();<br></br>            client.admin().indices().putMapping(mappingRequest).get();<br></br>        } catch (Exception e) {<br></br>            e.printStackTrace();<br></br>        }<br></br>    }<br></br>}<br></br>​<br></br>​

如果对Elasticsearch有较深入的了解,应该知道以下规则:

当索引不存在时,可以同时指定分片数和副本数

当索引已存在时,只能修改副本数

因此,在创建索引时就应确定分片和副本配置:

1):创建索引时直接指定分片数和副本数

/**<br></br> * 创建带配置的新索引<br></br> * */<br></br>@Test<br></br>public void createConfiguredIndex(){<br></br>    // 创建索引并设置配置<br></br>    Map<String, Integer> indexConfig = new HashMap<String, Integer>();<br></br>    indexConfig.put("number_of_shards", 5);<br></br>    indexConfig.put("number_of_replicas", 2);<br></br>    CreateIndexResponse indexResponse = esClient.admin().indices().prepareCreate("book_catalog").setSettings(indexConfig).get();<br></br>    System.out.println(indexResponse.toString());<br></br>​<br></br>}

2):然后创建映射信息时,可以忽略分片数和副本数,直接进行索引映射配置:

/**<br></br> * 索引映射配置类<br></br> */<br></br>public class ConfigureMappings {<br></br>    public static void setupMappings() throws UnknownHostException {<br></br>        TransportClient client = null;<br></br>        Settings settings = Settings.builder()<br></br>                .put("cluster.name", "production_cluster")<br></br>                .build();<br></br>        client = new PreBuiltTransportClient(settings)<br></br>                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node01"), 9300));<br></br>        System.out.println("========集群连接成功=============");<br></br>​<br></br>​<br></br>        XContentBuilder builder = null;<br></br>        try {<br></br>            builder = jsonBuilder()<br></br>                    .startObject()<br></br>                    .startObject("book_info").field("dynamic", "true")<br></br>                    .startObject("properties")<br></br>                    .startObject("isbn").field("type", "string").field("store", "yes").endObject()<br></br>                    .startObject("title").field("type", "string").field("store", "yes").field("analyzer", "ik_max_word").endObject()<br></br>                    .startObject("author").field("type", "string").field("store", "yes").endObject()<br></br>                    .startObject("price").field("type", "double").field("store", "yes").endObject()<br></br>                    .startObject("publishDate").field("type", "date").field("store", "yes").endObject()<br></br>                    .startObject("publisher").field("type", "string").field("store", "yes").endObject()<br></br>                    .startObject("summary").field("type", "string").field("store", "yes").field("analyzer", "ik_max_word").endObject()<br></br>                    .startObject("available").field("type", "boolean").field("store", "yes").field("index", "not_analyzed").endObject()<br></br>                    .endObject()<br></br>                    .endObject()<br></br>                    .endObject();<br></br>            PutMappingRequest mapping = Requests.putMappingRequest("book_catalog")<br></br>                    .type("book_info")<br></br>                    .source(builder);<br></br>            client.admin().indices().putMapping(mapping).get();<br></br>        } catch (Exception e) {<br></br>            e.printStackTrace();<br></br>        }<br></br>    }<br></br>}<br></br>​<br></br>​
标签: Elasticsearch

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。