Elasticsearch 每日一课:存储一个 float 值到 long 字段会怎么样?

今天我们要讨论的主题会让很多新手感到困惑,因为本身这个问题就挺难理解的。但如果你对 ES 比较熟悉,今天的内容也可以测试一下你对 ES 数据类型方面的知识是否牢靠。

一、默认的 Numeric 类型

首先,我们创建一个索引:

PUT orders/_doc/1
{
  "order_id": 1
}

如上示例,利用 Dynamic Mapping,系统会为自动为 orders 索引创建一个 Mapping,那么默认的情况下,order_id 这个字段会被推断为啥类型呢?

下面是这个 orders 索引的 Mapping:

# 获取 Mapping
GET orders/_mapping

# 结果:
{
  "orders" : {
    "mappings" : {
      "properties" : {
        "order_id" : { "type" : "long" }
      }
    }
  }
}

如上示例,很明显 Dynamic Mapping 推断的 order_id 为 long 类型。

那如果我们对这个 order_id 字段写入一些非整型数字会发生啥情况呢?在 Kibana 中执行以下命令来插入文档:

PUT orders/_doc/2
{
  "order_id": 2
}

PUT orders/_doc/3
{
  "order_id": "3"
}

PUT orders/_doc/4
{
  "order_id": 4.5
}

PUT orders/_doc
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个全面的根据泛型返回的 Elasticsearch 查询工具类的代码示例: ```java import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class ElasticsearchUtils<T> { private final RestHighLevelClient client; public ElasticsearchUtils(RestHighLevelClient client) { this.client = client; } /** * 根据关键词查询ES中的数据 * * @param indexName 索引名称 * @param keyword 查询关键词 * @param clazz 查询结果类型 * @param size 返回结果数量 * @return 返回查询结果列表 */ public List<T> searchByKeyword(String indexName, String keyword, Class<T> clazz, int size) throws IOException { List<T> resultList = new ArrayList<>(); // 创建查询请求 SearchRequest searchRequest = new SearchRequest(indexName); // 构建查询条件 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchQuery("content", keyword)); searchSourceBuilder.timeout(TimeValue.timeValueSeconds(60)); searchSourceBuilder.size(size); // 构建高亮显示 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field("content"); highlightBuilder.requireFieldMatch(false); highlightBuilder.preTags("<span style=\"color:red\">"); highlightBuilder.postTags("</span>"); searchSourceBuilder.highlighter(highlightBuilder); searchRequest.source(searchSourceBuilder); // 执行查询 SearchResponse searchResponse = client.search(searchRequest); // 解析查询结果 SearchHit[] searchHits = searchResponse.getHits().getHits(); for (SearchHit hit : searchHits) { T obj = parseHitSource(hit.getSourceAsMap(), clazz); // 解析高亮显示 Map<String, HighlightField> highlightFields = hit.getHighlightFields(); for (Map.Entry<String, HighlightField> entry : highlightFields.entrySet()) { String fieldName = entry.getKey(); HighlightField highlightField = entry.getValue(); if (highlightField != null) { Field field = getField(clazz, fieldName); if (field != null) { setFieldValue(obj, field, highlightField.fragments()[0].toString()); } } } resultList.add(obj); } return resultList; } /** * 解析查询结果中的hit源数据,并转换为指定类型的对象 * * @param sourceMap hit源数据 * @param clazz 目标类型 * @return 返回转换后的对象 */ private T parseHitSource(Map<String, Object> sourceMap, Class<T> clazz) { Map<String, Object> resultMap = new HashMap<>(); // 将Map中的key转换为小写,避免与Java类中的字段出现不匹配 for (Map.Entry<String, Object> entry : sourceMap.entrySet()) { resultMap.put(entry.getKey().toLowerCase(), entry.getValue()); } return JsonUtils.fromJson(JsonUtils.toJson(resultMap), clazz); } /** * 获取Java类中指定名称的字段 * * @param clazz Java类 * @param fieldName 字段名称 * @return 返回字段对象 */ private Field getField(Class<?> clazz, String fieldName) { Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.getName().equalsIgnoreCase(fieldName)) { field.setAccessible(true); return field; } } return null; } /** * 设置Java对象中指定字段的值 * * @param obj Java对象 * @param field 字段对象 * @param value 字段值 */ private void setFieldValue(T obj, Field field, String value) { try { if (field.getType() == String.class) { field.set(obj, value); } else if (field.getType() == Integer.class || field.getType() == int.class) { field.set(obj, Integer.parseInt(value)); } else if (field.getType() == Long.class || field.getType() == long.class) { field.set(obj, Long.parseLong(value)); } else if (field.getType() == Double.class || field.getType() == double.class) { field.set(obj, Double.parseDouble(value)); } else if (field.getType() == Float.class || field.getType() == float.class) { field.set(obj, Float.parseFloat(value)); } else if (field.getType() == Boolean.class || field.getType() == boolean.class) { field.set(obj, Boolean.parseBoolean(value)); } } catch (IllegalAccessException e) { e.printStackTrace(); } } } ``` 这个工具类的主要作用是根据关键词查询 Elasticsearch 中的数据,并返回查询结果列表。其中,使用了 Elasticsearch 的 Java 客户端 RestHighLevelClient,以及构建查询条件的 SearchSourceBuilder。查询条件中使用了 matchQuery 方法,可以通过关键词查询指定字段(这里是 content 字段)的匹配结果。同时,还使用了 HighlightBuilder 对结果中匹配的内容进行高亮显示。在解析查询结果时,使用了反射机制将 Elasticsearch 中的 hit 源数据转换为指定类型的 Java 对象,并在解析高亮显示时,使用反射机制设置 Java 对象中指定字段的值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值