当前位置: 首页 > news >正文

hive中get_json_object函数不支持解析json中文key

问题

今天在 Hive 中 get_json_object 函数解析 json 串的时候,发现函数不支持解析 json 中文 key。
例如:

select get_json_object('{ "姓名":"张三" , "年龄":"18" }', '$.姓名');

我们希望的结果是得到姓名对应的值张三,而运行之后的结果为 NULL 值。

select get_json_object('{ "abc姓名":"张三" , "abc":"18" }', '$.abc姓名');

我们希望的结果是得到姓名对应的值张三,而运行之后的结果为 18

产生问题的原因

是什么原因导致的呢?我们查看 Hive 官网中 get_json_object 函数的介绍,可以发现 get_json_object 函数不能解析 json 里面中文的 key,如下图所示:
在这里插入图片描述
json 路径只能包含字符 [0-9a-z_],即不能包含 大写或特殊字符 。此外,键不能以数字开头。

那为什么 json 路径只能包含字符 [0-9a-z_] 呢?

通过查看源码我们发现 get_json_object 对应的 UDF 类的源码如下:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Iterators;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;/*** UDFJson.*/
@Description(name = "get_json_object",value = "_FUNC_(json_txt, path) - Extract a json object from path ",extended = "Extract json object from a json string based on json path "+ "specified, and return json string of the extracted json object. It "+ "will return null if the input json string is invalid.\n"+ "A limited version of JSONPath supported:\n"+ "  $   : Root object\n"+ "  .   : Child operator\n"+ "  []  : Subscript operator for array\n"+ "  *   : Wildcard for []\n"+ "Syntax not supported that's worth noticing:\n"+ "  ''  : Zero length string as key\n"+ "  ..  : Recursive descent\n"+ "  @   : Current object/element\n"+ "  ()  : Script expression\n"+ "  ?() : Filter (script) expression.\n"+ "  [,] : Union operator\n"+ "  [start:end:step] : array slice operator\n")//定义了一个名为UDFJson的类,继承自UDF类。
public class UDFGetJsonObjectCN extends UDF {//定义一个静态正则表达式模式,用于匹配JSON路径中的键。//匹配英文key:匹配一个或多个大写字母、小写字母、数字、下划线、连字符、冒号或空格。private static final Pattern patternKey = Pattern.compile("^([a-zA-Z0-9_\\-\\:\\s]+).*");//定义一个静态正则表达式模式,用于匹配JSON路径中的索引。private static final Pattern patternIndex = Pattern.compile("\\[([0-9]+|\\*)\\]");//创建一个ObjectMapper对象,用于解析JSON字符串。private static final ObjectMapper objectMapper = new ObjectMapper();//创建一个JavaType对象,用于表示Map类型。private static final JavaType MAP_TYPE = objectMapper.getTypeFactory().constructType(Map.class);//创建一个JavaType对象,用于表示List类型。private static final JavaType LIST_TYPE = objectMapper.getTypeFactory().constructType(List.class);//静态代码块,用于配置ObjectMapper的一些特性。static {// Allows for unescaped ASCII control characters in JSON valuesobjectMapper.enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature());// Enabled to accept quoting of all character backslash qooting mechanismobjectMapper.enable(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature());}// An LRU cache using a linked hash map//定义了一个静态内部类HashCache,用作LRU缓存。static class HashCache<K, V> extends LinkedHashMap<K, V> {private static final int CACHE_SIZE = 16;private static final int INIT_SIZE = 32;private static final float LOAD_FACTOR = 0.6f;HashCache() {super(INIT_SIZE, LOAD_FACTOR);}private static final long serialVersionUID = 1;@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {return size() > CACHE_SIZE;}}//声明了一个名为extractObjectCache的HashMap对象,用于缓存已提取的JSON对象。Map<String, Object> extractObjectCache = new HashCache<String, Object>();//声明了一个名为pathExprCache的HashMap对象,用于缓存已解析的JSON路径表达式。Map<String, String[]> pathExprCache = new HashCache<String, String[]>();//声明了一个名为indexListCache的HashMap对象,用于缓存已解析的JSON路径中的索引列表。Map<String, ArrayList<String>> indexListCache =new HashCache<String, ArrayList<String>>();//声明了一个名为mKeyGroup1Cache的HashMap对象,用于缓存JSON路径中的键。Map<String, String> mKeyGroup1Cache = new HashCache<String, String>();//声明了一个名为mKeyMatchesCache的HashMap对象,用于缓存JSON路径中的键是否匹配的结果。Map<String, Boolean> mKeyMatchesCache = new HashCache<String, Boolean>();//构造函数,没有参数。public UDFGetJsonObjectCN() {}/*** Extract json object from a json string based on json path specified, and* return json string of the extracted json object. It will return null if the* input json string is invalid.** A limited version of JSONPath supported: $ : Root object . : Child operator* [] : Subscript operator for array * : Wildcard for []** Syntax not supported that's worth noticing: '' : Zero length string as key* .. : Recursive descent &amp;#064; : Current object/element () : Script* expression ?() : Filter (script) expression. [,] : Union operator* [start:end:step] : array slice operator** @param jsonString*          the json string.* @param pathString*          the json path expression.* @return json string or null when an error happens.*///evaluate方法,用于提取指定路径的JSON对象并返回JSON字符串。public Text evaluate(String jsonString, String pathString) {if (jsonString == null || jsonString.isEmpty() || pathString == null|| pathString.isEmpty() || pathString.charAt(0) != '$') {return null;}int pathExprStart = 1;boolean unknownType = pathString.equals("$");boolean isRootArray = false;if (pathString.length() > 1) {if (pathString.charAt(1) == '[') {pathExprStart = 0;isRootArray = true;} else if (pathString.charAt(1) == '.') {isRootArray = pathString.length() > 2 && pathString.charAt(2) == '[';} else {return null;}}// Cache pathExprString[] pathExpr = pathExprCache.get(pathString);if (pathExpr == null) {pathExpr = pathString.split("\\.", -1);pathExprCache.put(pathString, pathExpr);}// Cache extractObjectObject extractObject = extractObjectCache.get(jsonString);if (extractObject == null) {if (unknownType) {try {extractObject = objectMapper.readValue(jsonString, LIST_TYPE);} catch (Exception e) {// Ignore exception}if (extractObject == null) {try {extractObject = objectMapper.readValue(jsonString, MAP_TYPE);} catch (Exception e) {return null;}}} else {JavaType javaType = isRootArray ? LIST_TYPE : MAP_TYPE;try {extractObject = objectMapper.readValue(jsonString, javaType);} catch (Exception e) {return null;}}extractObjectCache.put(jsonString, extractObject);}for (int i = pathExprStart; i < pathExpr.length; i++) {if (extractObject == null) {return null;}extractObject = extract(extractObject, pathExpr[i], i == pathExprStart && isRootArray);}Text result = new Text();if (extractObject instanceof Map || extractObject instanceof List) {try {result.set(objectMapper.writeValueAsString(extractObject));} catch (Exception e) {return null;}} else if (extractObject != null) {result.set(extractObject.toString());} else {return null;}return result;}//extract方法,递归地提取JSON对象。private Object extract(Object json, String path, boolean skipMapProc) {// skip MAP processing for the first path element if root is arrayif (!skipMapProc) {// Cache patternkey.matcher(path).matches()Matcher mKey = null;Boolean mKeyMatches = mKeyMatchesCache.get(path);if (mKeyMatches == null) {mKey = patternKey.matcher(path);mKeyMatches = mKey.matches() ? Boolean.TRUE : Boolean.FALSE;mKeyMatchesCache.put(path, mKeyMatches);}if (!mKeyMatches.booleanValue()) {return null;}// Cache mkey.group(1)String mKeyGroup1 = mKeyGroup1Cache.get(path);if (mKeyGroup1 == null) {if (mKey == null) {mKey = patternKey.matcher(path);mKeyMatches = mKey.matches() ? Boolean.TRUE : Boolean.FALSE;mKeyMatchesCache.put(path, mKeyMatches);if (!mKeyMatches.booleanValue()) {return null;}}mKeyGroup1 = mKey.group(1);mKeyGroup1Cache.put(path, mKeyGroup1);}json = extract_json_withkey(json, mKeyGroup1);}// Cache indexListArrayList<String> indexList = indexListCache.get(path);if (indexList == null) {Matcher mIndex = patternIndex.matcher(path);indexList = new ArrayList<String>();while (mIndex.find()) {indexList.add(mIndex.group(1));}indexListCache.put(path, indexList);}if (indexList.size() > 0) {json = extract_json_withindex(json, indexList);}return json;}//创建一个名为jsonList的AddingList对象,用于存储提取出来的JSON对象。private transient AddingList jsonList = new AddingList();//定义了一个静态内部类AddingList,继承自ArrayList<Object>,用于添加JSON对象到jsonList中。private static class AddingList extends ArrayList<Object> {private static final long serialVersionUID = 1L;@Overridepublic Iterator<Object> iterator() {return Iterators.forArray(toArray());}@Overridepublic void removeRange(int fromIndex, int toIndex) {super.removeRange(fromIndex, toIndex);}};//extract_json_withindex方法,根据JSON路径中的索引提取JSON对象。@SuppressWarnings("unchecked")private Object extract_json_withindex(Object json, ArrayList<String> indexList) {jsonList.clear();jsonList.add(json);for (String index : indexList) {int targets = jsonList.size();if (index.equalsIgnoreCase("*")) {for (Object array : jsonList) {if (array instanceof List) {for (int j = 0; j < ((List<Object>)array).size(); j++) {jsonList.add(((List<Object>)array).get(j));}}}} else {for (Object array : jsonList) {int indexValue = Integer.parseInt(index);if (!(array instanceof List)) {continue;}List<Object> list = (List<Object>) array;if (indexValue >= list.size()) {continue;}jsonList.add(list.get(indexValue));}}if (jsonList.size() == targets) {return null;}jsonList.removeRange(0, targets);}if (jsonList.isEmpty()) {return null;}return (jsonList.size() > 1) ? new ArrayList<Object>(jsonList) : jsonList.get(0);}//extract_json_withkey方法,根据JSON路径中的键提取JSON对象。@SuppressWarnings("unchecked")private Object extract_json_withkey(Object json, String path) {if (json instanceof List) {List<Object> jsonArray = new ArrayList<Object>();for (int i = 0; i < ((List<Object>) json).size(); i++) {Object json_elem = ((List<Object>) json).get(i);Object json_obj = null;if (json_elem instanceof Map) {json_obj = ((Map<String, Object>) json_elem).get(path);} else {continue;}if (json_obj instanceof List) {for (int j = 0; j < ((List<Object>) json_obj).size(); j++) {jsonArray.add(((List<Object>) json_obj).get(j));}} else if (json_obj != null) {jsonArray.add(json_obj);}}return (jsonArray.size() == 0) ? null : jsonArray;} else if (json instanceof Map) {return ((Map<String, Object>) json).get(path);} else {return null;}}
}

代码做了一些注释,我们可以发现 private final Pattern patternKey = Pattern.compile("^([a-zA-Z0-9_\\-\\:\\s]+).*"); 这个就是匹配 key 的模式串,它的意思是匹配以数字、字母、_、-、:、空格 为开头的字符串。那么这个匹配模式串就决定了,get_json_object 函数无法匹配出 key 中带中文的键值对,即select get_json_object('{ "姓名":"张三" , "年龄":"18" }', '$.姓名'); 结果为 null;而 select get_json_object('{ "abc姓名":"张三" , "abc":"18" }', '$.abc姓名'); 中只能匹配以数字、字母、_、-、:、空格 为开头的字符串,所以将 abc姓名 中的 abc 当作 key 去取 value 值,所以得到的值为18

解决办法

知道问题的原因了,那么我们怎么解决这个问题呢,其实很简单,我们只需要修改代码中匹配 key 的正则表达式就可以了。
其实我们可以将 get_json_object 函数的源码拿出来重新写一个 UDF 函数就可以了。

Hive-2.1.1 版本

需要注意自己 Hive 的版本,我们以 Hive-2.1.1 版本为例,代码如下:

package com.yan.hive.udf;import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import com.google.common.collect.Iterators;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser.Feature;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.TypeFactory;
import org.codehaus.jackson.type.JavaType;/*** UDFJson.**/
@Description(name = "get_json_object_cn",value = "_FUNC_(json_txt, path) - Extract a json object from path ",extended = "Extract json object from a json string based on json path "+ "specified, and return json string of the extracted json object. It "+ "will return null if the input json string is invalid.\n"+ "A limited version of JSONPath supported:\n"+ "  $   : Root object\n"+ "  .   : Child operator\n"+ "  []  : Subscript operator for array\n"+ "  *   : Wildcard for []\n"+ "Syntax not supported that's worth noticing:\n"+ "  ''  : Zero length string as key\n"+ "  ..  : Recursive descent\n"+ "  &amp;#064;   : Current object/element\n"+ "  ()  : Script expression\n"+ "  ?() : Filter (script) expression.\n"+ "  [,] : Union operator\n"+ "  [start:end:step] : array slice operator\n")
public class UDFGetJsonObjectCN extends UDF {//private final Pattern patternKey = Pattern.compile("^([a-zA-Z0-9_\\-\\:\\s]+).*");private final Pattern patternKey = Pattern.compile("^([^\\[\\]]+).*");private final Pattern patternIndex = Pattern.compile("\\[([0-9]+|\\*)\\]");private static final JsonFactory JSON_FACTORY = new JsonFactory();static {// Allows for unescaped ASCII control characters in JSON valuesJSON_FACTORY.enable(Feature.ALLOW_UNQUOTED_CONTROL_CHARS);// Enabled to accept quoting of all character backslash qooting mechanismJSON_FACTORY.enable(Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER);}private static final ObjectMapper MAPPER = new ObjectMapper(JSON_FACTORY);private static final JavaType MAP_TYPE = TypeFactory.fromClass(Map.class);private static final JavaType LIST_TYPE = TypeFactory.fromClass(List.class);// An LRU cache using a linked hash mapstatic class HashCache<K, V> extends LinkedHashMap<K, V> {private static final int CACHE_SIZE = 16;private static final int INIT_SIZE = 32;private static final float LOAD_FACTOR = 0.6f;HashCache() {super(INIT_SIZE, LOAD_FACTOR);}private static final long serialVersionUID = 1;@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {return size() > CACHE_SIZE;}}static Map<String, Object> extractObjectCache = new HashCache<String, Object>();static Map<String, String[]> pathExprCache = new HashCache<String, String[]>();static Map<String, ArrayList<String>> indexListCache =new HashCache<String, ArrayList<String>>();static Map<String, String> mKeyGroup1Cache = new HashCache<String, String>();static Map<String, Boolean> mKeyMatchesCache = new HashCache<String, Boolean>();Text result = new Text();public UDFGetJsonObjectCN() {}/*** Extract json object from a json string based on json path specified, and* return json string of the extracted json object. It will return null if the* input json string is invalid.** A limited version of JSONPath supported: $ : Root object . : Child operator* [] : Subscript operator for array * : Wildcard for []** Syntax not supported that's worth noticing: '' : Zero length string as key* .. : Recursive descent &amp;#064; : Current object/element () : Script* expression ?() : Filter (script) expression. [,] : Union operator* [start:end:step] : array slice operator** @param jsonString*          the json string.* @param pathString*          the json path expression.* @return json string or null when an error happens.*/public Text evaluate(String jsonString, String pathString) {if (jsonString == null || jsonString.isEmpty() || pathString == null|| pathString.isEmpty() || pathString.charAt(0) != '$') {return null;}int pathExprStart = 1;boolean isRootArray = false;if (pathString.length() > 1) {if (pathString.charAt(1) == '[') {pathExprStart = 0;isRootArray = true;} else if (pathString.charAt(1) == '.') {isRootArray = pathString.length() > 2 && pathString.charAt(2) == '[';} else {return null;}}// Cache pathExprString[] pathExpr = pathExprCache.get(pathString);if (pathExpr == null) {pathExpr = pathString.split("\\.", -1);pathExprCache.put(pathString, pathExpr);}// Cache extractObjectObject extractObject = extractObjectCache.get(jsonString);if (extractObject == null) {JavaType javaType = isRootArray ? LIST_TYPE : MAP_TYPE;try {extractObject = MAPPER.readValue(jsonString, javaType);} catch (Exception e) {return null;}extractObjectCache.put(jsonString, extractObject);}for (int i = pathExprStart; i < pathExpr.length; i++) {if (extractObject == null) {return null;}extractObject = extract(extractObject, pathExpr[i], i == pathExprStart && isRootArray);}if (extractObject instanceof Map || extractObject instanceof List) {try {result.set(MAPPER.writeValueAsString(extractObject));} catch (Exception e) {return null;}} else if (extractObject != null) {result.set(extractObject.toString());} else {return null;}return result;}private Object extract(Object json, String path, boolean skipMapProc) {// skip MAP processing for the first path element if root is arrayif (!skipMapProc) {// Cache patternkey.matcher(path).matches()Matcher mKey = null;Boolean mKeyMatches = mKeyMatchesCache.get(path);if (mKeyMatches == null) {mKey = patternKey.matcher(path);mKeyMatches = mKey.matches() ? Boolean.TRUE : Boolean.FALSE;mKeyMatchesCache.put(path, mKeyMatches);}if (!mKeyMatches.booleanValue()) {return null;}// Cache mkey.group(1)String mKeyGroup1 = mKeyGroup1Cache.get(path);if (mKeyGroup1 == null) {if (mKey == null) {mKey = patternKey.matcher(path);mKeyMatches = mKey.matches() ? Boolean.TRUE : Boolean.FALSE;mKeyMatchesCache.put(path, mKeyMatches);if (!mKeyMatches.booleanValue()) {return null;}}mKeyGroup1 = mKey.group(1);mKeyGroup1Cache.put(path, mKeyGroup1);}json = extract_json_withkey(json, mKeyGroup1);}// Cache indexListArrayList<String> indexList = indexListCache.get(path);if (indexList == null) {Matcher mIndex = patternIndex.matcher(path);indexList = new ArrayList<String>();while (mIndex.find()) {indexList.add(mIndex.group(1));}indexListCache.put(path, indexList);}if (indexList.size() > 0) {json = extract_json_withindex(json, indexList);}return json;}private transient AddingList jsonList = new AddingList();private static class AddingList extends ArrayList<Object> {@Overridepublic Iterator<Object> iterator() {return Iterators.forArray(toArray());}@Overridepublic void removeRange(int fromIndex, int toIndex) {super.removeRange(fromIndex, toIndex);}};@SuppressWarnings("unchecked")private Object extract_json_withindex(Object json, ArrayList<String> indexList) {jsonList.clear();jsonList.add(json);for (String index : indexList) {int targets = jsonList.size();if (index.equalsIgnoreCase("*")) {for (Object array : jsonList) {if (array instanceof List) {for (int j = 0; j < ((List<Object>)array).size(); j++) {jsonList.add(((List<Object>)array).get(j));}}}} else {for (Object array : jsonList) {int indexValue = Integer.parseInt(index);if (!(array instanceof List)) {continue;}List<Object> list = (List<Object>) array;if (indexValue >= list.size()) {continue;}jsonList.add(list.get(indexValue));}}if (jsonList.size() == targets) {return null;}jsonList.removeRange(0, targets);}if (jsonList.isEmpty()) {return null;}return (jsonList.size() > 1) ? new ArrayList<Object>(jsonList) : jsonList.get(0);}@SuppressWarnings("unchecked")private Object extract_json_withkey(Object json, String path) {if (json instanceof List) {List<Object> jsonArray = new ArrayList<Object>();for (int i = 0; i < ((List<Object>) json).size(); i++) {Object json_elem = ((List<Object>) json).get(i);Object json_obj = null;if (json_elem instanceof Map) {json_obj = ((Map<String, Object>) json_elem).get(path);} else {continue;}if (json_obj instanceof List) {for (int j = 0; j < ((List<Object>) json_obj).size(); j++) {jsonArray.add(((List<Object>) json_obj).get(j));}} else if (json_obj != null) {jsonArray.add(json_obj);}}return (jsonArray.size() == 0) ? null : jsonArray;} else if (json instanceof Map) {return ((Map<String, Object>) json).get(path);} else {return null;}}
}

需要导入的依赖,要和自己集群的版本契合,Hadoop 的版本及 Hive 的版本。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.atguigu.hive</groupId><artifactId>hivetest</artifactId><version>1.0-SNAPSHOT</version><properties><hadoop.version>3.0.0</hadoop.version><hive.version>2.1.1</hive.version><jackson.version>1.9.2</jackson.version><guava.version>14.0.1</guava.version></properties><dependencies><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>${hive.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc --><dependency><groupId>org.apache.hive</groupId><artifactId>hive-jdbc</artifactId><version>${hive.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>${guava.version}</version></dependency><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-core-asl</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-mapper-asl</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-jaxrs</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-xc</artifactId><version>${jackson.version}</version></dependency></dependencies></project>

注意: 因为上述UDF中也用到了 com.google.guavaorg.codehaus.jackson,所以这两个依赖要和 hive 版本中所用的依赖版本一致。

Hive-4.0.0 版本

package com.yan.hive.udf;import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Iterators;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;/*** @author Yan* @create 2023-08-05 22:21* hive解析json中文key*/
@Description(name = "get_json_object_cn",value = "_FUNC_(json_txt, path) - Extract a json object from path ",extended = "Extract json object from a json string based on json path "+ "specified, and return json string of the extracted json object. It "+ "will return null if the input json string is invalid.\n"+ "A limited version of JSONPath supported:\n"+ "  $   : Root object\n"+ "  .   : Child operator\n"+ "  []  : Subscript operator for array\n"+ "  *   : Wildcard for []\n"+ "Syntax not supported that's worth noticing:\n"+ "  ''  : Zero length string as key\n"+ "  ..  : Recursive descent\n"+ "  &amp;#064;   : Current object/element\n"+ "  ()  : Script expression\n"+ "  ?() : Filter (script) expression.\n"+ "  [,] : Union operator\n"+ "  [start:end:step] : array slice operator\n")//定义了一个名为UDFJson的类,继承自UDF类。
public class UDFGetJsonObjectCN extends UDF {//定义一个静态正则表达式模式,用于匹配JSON路径中的键。//匹配英文key:匹配一个或多个大写字母、小写字母、数字、下划线、连字符、冒号或空格。//private static final Pattern patternKey = Pattern.compile("^([a-zA-Z0-9_\\-\\:\\s]+).*");//可以匹配中文,\\p{L}来匹配任意Unicode字母字符,包括中文字符:英文、数字、下划线、连字符、冒号、空格和中文字符。//private static final Pattern patternKey = Pattern.compile("^([a-zA-Z0-9_\\-\\:\\s\\p{L}]+).*");//可以匹配中文,\\p{L}来匹配任意Unicode字母字符,包括中文字符,但不包含特殊字符,特殊字符需自己添加//private static final Pattern patternKey = Pattern.compile("^([a-zA-Z0-9_\\-\\:\\s?%*+\\p{L}]+).*");//可以匹配中文,包含特殊字符,但不包含英文下的点(.);还有就是匹配不到路径中的索引了//private static final Pattern patternKey = Pattern.compile("^(.+).*");//可以匹配中文,包含特殊字符,不包中括号"[]",但不包含英文下的点(.);这样就可以匹配路径中的索引了private static final Pattern patternKey = Pattern.compile("^([^\\[\\]]+).*");//定义一个静态正则表达式模式,用于匹配JSON路径中的索引。private static final Pattern patternIndex = Pattern.compile("\\[([0-9]+|\\*)\\]");//创建一个ObjectMapper对象,用于解析JSON字符串。private static final ObjectMapper objectMapper = new ObjectMapper();//创建一个JavaType对象,用于表示Map类型。private static final JavaType MAP_TYPE = objectMapper.getTypeFactory().constructType(Map.class);//创建一个JavaType对象,用于表示List类型。private static final JavaType LIST_TYPE = objectMapper.getTypeFactory().constructType(List.class);//静态代码块,用于配置ObjectMapper的一些特性。static {// Allows for unescaped ASCII control characters in JSON valuesobjectMapper.enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature());// Enabled to accept quoting of all character backslash qooting mechanismobjectMapper.enable(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature());}// An LRU cache using a linked hash map//定义了一个静态内部类HashCache,用作LRU缓存。static class HashCache<K, V> extends LinkedHashMap<K, V> {private static final int CACHE_SIZE = 16;private static final int INIT_SIZE = 32;private static final float LOAD_FACTOR = 0.6f;HashCache() {super(INIT_SIZE, LOAD_FACTOR);}private static final long serialVersionUID = 1;@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {return size() > CACHE_SIZE;}}//声明了一个名为extractObjectCache的HashMap对象,用于缓存已提取的JSON对象。Map<String, Object> extractObjectCache = new HashCache<String, Object>();//声明了一个名为pathExprCache的HashMap对象,用于缓存已解析的JSON路径表达式。Map<String, String[]> pathExprCache = new HashCache<String, String[]>();//声明了一个名为indexListCache的HashMap对象,用于缓存已解析的JSON路径中的索引列表。Map<String, ArrayList<String>> indexListCache =new HashCache<String, ArrayList<String>>();//声明了一个名为mKeyGroup1Cache的HashMap对象,用于缓存JSON路径中的键。Map<String, String> mKeyGroup1Cache = new HashCache<String, String>();//声明了一个名为mKeyMatchesCache的HashMap对象,用于缓存JSON路径中的键是否匹配的结果。Map<String, Boolean> mKeyMatchesCache = new HashCache<String, Boolean>();//构造函数,没有参数。public UDFGetJsonObjectCN() {}/*** Extract json object from a json string based on json path specified, and* return json string of the extracted json object. It will return null if the* input json string is invalid.** A limited version of JSONPath supported: $ : Root object . : Child operator* [] : Subscript operator for array * : Wildcard for []** Syntax not supported that's worth noticing: '' : Zero length string as key* .. : Recursive descent &amp;#064; : Current object/element () : Script* expression ?() : Filter (script) expression. [,] : Union operator* [start:end:step] : array slice operator** @param jsonString*          the json string.* @param pathString*          the json path expression.* @return json string or null when an error happens.*///evaluate方法,用于提取指定路径的JSON对象并返回JSON字符串。public Text evaluate(String jsonString, String pathString) {if (jsonString == null || jsonString.isEmpty() || pathString == null|| pathString.isEmpty() || pathString.charAt(0) != '$') {return null;}int pathExprStart = 1;boolean unknownType = pathString.equals("$");boolean isRootArray = false;if (pathString.length() > 1) {if (pathString.charAt(1) == '[') {pathExprStart = 0;isRootArray = true;} else if (pathString.charAt(1) == '.') {isRootArray = pathString.length() > 2 && pathString.charAt(2) == '[';} else {return null;}}// Cache pathExprString[] pathExpr = pathExprCache.get(pathString);if (pathExpr == null) {pathExpr = pathString.split("\\.", -1);pathExprCache.put(pathString, pathExpr);}// Cache extractObjectObject extractObject = extractObjectCache.get(jsonString);if (extractObject == null) {if (unknownType) {try {extractObject = objectMapper.readValue(jsonString, LIST_TYPE);} catch (Exception e) {// Ignore exception}if (extractObject == null) {try {extractObject = objectMapper.readValue(jsonString, MAP_TYPE);} catch (Exception e) {return null;}}} else {JavaType javaType = isRootArray ? LIST_TYPE : MAP_TYPE;try {extractObject = objectMapper.readValue(jsonString, javaType);} catch (Exception e) {return null;}}extractObjectCache.put(jsonString, extractObject);}for (int i = pathExprStart; i < pathExpr.length; i++) {if (extractObject == null) {return null;}extractObject = extract(extractObject, pathExpr[i], i == pathExprStart && isRootArray);}Text result = new Text();if (extractObject instanceof Map || extractObject instanceof List) {try {result.set(objectMapper.writeValueAsString(extractObject));} catch (Exception e) {return null;}} else if (extractObject != null) {result.set(extractObject.toString());} else {return null;}return result;}//extract方法,递归地提取JSON对象。private Object extract(Object json, String path, boolean skipMapProc) {// skip MAP processing for the first path element if root is arrayif (!skipMapProc) {// Cache patternkey.matcher(path).matches()Matcher mKey = null;Boolean mKeyMatches = mKeyMatchesCache.get(path);if (mKeyMatches == null) {mKey = patternKey.matcher(path);mKeyMatches = mKey.matches() ? Boolean.TRUE : Boolean.FALSE;mKeyMatchesCache.put(path, mKeyMatches);}if (!mKeyMatches.booleanValue()) {return null;}// Cache mkey.group(1)String mKeyGroup1 = mKeyGroup1Cache.get(path);if (mKeyGroup1 == null) {if (mKey == null) {mKey = patternKey.matcher(path);mKeyMatches = mKey.matches() ? Boolean.TRUE : Boolean.FALSE;mKeyMatchesCache.put(path, mKeyMatches);if (!mKeyMatches.booleanValue()) {return null;}}mKeyGroup1 = mKey.group(1);mKeyGroup1Cache.put(path, mKeyGroup1);}json = extract_json_withkey(json, mKeyGroup1);}// Cache indexListArrayList<String> indexList = indexListCache.get(path);if (indexList == null) {Matcher mIndex = patternIndex.matcher(path);indexList = new ArrayList<String>();while (mIndex.find()) {indexList.add(mIndex.group(1));}indexListCache.put(path, indexList);}if (indexList.size() > 0) {json = extract_json_withindex(json, indexList);}return json;}//创建一个名为jsonList的AddingList对象,用于存储提取出来的JSON对象。private transient AddingList jsonList = new AddingList();//定义了一个静态内部类AddingList,继承自ArrayList<Object>,用于添加JSON对象到jsonList中。private static class AddingList extends ArrayList<Object> {private static final long serialVersionUID = 1L;@Overridepublic Iterator<Object> iterator() {return Iterators.forArray(toArray());}@Overridepublic void removeRange(int fromIndex, int toIndex) {super.removeRange(fromIndex, toIndex);}};//extract_json_withindex方法,根据JSON路径中的索引提取JSON对象。@SuppressWarnings("unchecked")private Object extract_json_withindex(Object json, ArrayList<String> indexList) {jsonList.clear();jsonList.add(json);for (String index : indexList) {int targets = jsonList.size();if (index.equalsIgnoreCase("*")) {for (Object array : jsonList) {if (array instanceof List) {for (int j = 0; j < ((List<Object>)array).size(); j++) {jsonList.add(((List<Object>)array).get(j));}}}} else {for (Object array : jsonList) {int indexValue = Integer.parseInt(index);if (!(array instanceof List)) {continue;}List<Object> list = (List<Object>) array;if (indexValue >= list.size()) {continue;}jsonList.add(list.get(indexValue));}}if (jsonList.size() == targets) {return null;}jsonList.removeRange(0, targets);}if (jsonList.isEmpty()) {return null;}return (jsonList.size() > 1) ? new ArrayList<Object>(jsonList) : jsonList.get(0);}//extract_json_withkey方法,根据JSON路径中的键提取JSON对象。@SuppressWarnings("unchecked")private Object extract_json_withkey(Object json, String path) {if (json instanceof List) {List<Object> jsonArray = new ArrayList<Object>();for (int i = 0; i < ((List<Object>) json).size(); i++) {Object json_elem = ((List<Object>) json).get(i);Object json_obj = null;if (json_elem instanceof Map) {json_obj = ((Map<String, Object>) json_elem).get(path);} else {continue;}if (json_obj instanceof List) {for (int j = 0; j < ((List<Object>) json_obj).size(); j++) {jsonArray.add(((List<Object>) json_obj).get(j));}} else if (json_obj != null) {jsonArray.add(json_obj);}}return (jsonArray.size() == 0) ? null : jsonArray;} else if (json instanceof Map) {return ((Map<String, Object>) json).get(path);} else {return null;}}
}

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.atguigu.hive</groupId><artifactId>hivetest</artifactId><version>1.0-SNAPSHOT</version><properties><hadoop.version>3.3.1</hadoop.version><hive.version>4.0.0</hive.version><jackson.version>2.13.5</jackson.version><guava.version>22.0</guava.version></properties><dependencies><dependency><groupId>com.fasterxml.jackson</groupId><artifactId>jackson-bom</artifactId><version>${jackson.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>${guava.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-jdbc</artifactId><version>${hive.version}</version></dependency></dependencies></project>

Hive 版本不同,之间的依赖可能就有些许差距,如果不注意的话可能会报依赖错误。

参考文章:

get_json_object不能解析json里面中文的key

get_json_object源码

impala&hive自定义UDF解析json中文key

相关文章:

hive中get_json_object函数不支持解析json中文key

问题 今天在 Hive 中 get_json_object 函数解析 json 串的时候&#xff0c;发现函数不支持解析 json 中文 key。 例如&#xff1a; select get_json_object({ "姓名":"张三" , "年龄":"18" }, $.姓名);我们希望的结果是得到姓名对应…...

Azure VM上意外禁用NIC如何还原恢复

创建一个windows虚拟机&#xff0c;并远程连接管理员的方式打开powershell 首先查看虚拟网卡&#xff0c;netsh interface show interface 然后禁用虚拟网卡 ,netsh interface set interface Ethernet disable 去Azure虚拟机控制台&#xff0c;打开串行控制台 控制台中键入cmd,…...

神经网络简单理解:机场登机

目录 神经网络简单理解&#xff1a;机场登机 ​编辑 激活函数&#xff1a;转为非线性问题 ​编辑 激活函数ReLU 通过神经元升维&#xff08;神经元数量&#xff09;&#xff1a;提升线性转化能力 通过增加隐藏层&#xff1a;增加非线性转化能力​编辑 模型越大&#xff0c;…...

Sping源码(七)— 后置处理器

简单回顾一下上一篇文章&#xff0c;是在BeanFacroty创建完之后&#xff0c;可以通过Editor和EditorRegistrar实现对类属性的自定义扩展&#xff0c;以及忽略要自动装配的Aware接口。 本篇帖子会顺着refresh()主流程方法接着向下执行。在讲invokeBeanFactoryPostProcessors方法…...

docker导出、导入镜像、提交

导出镜像到本地&#xff0c;然后可以通过压缩包的方式传输。 导出&#xff1a;docker image save 镜像名:版本号 > /home/quxiao/javatest.tgz 导入&#xff1a;docker image load -i /home/quxiao/javatest.tgz 删除镜像就得先删除容器&#xff0c;当你每运行一次镜像&…...

shell的变量

一、什么是变量 二、变量的命名 三、查看变量的值 env显示全局变量&#xff0c;刚刚定义的root_mess是局部变量 四、变量的定义 旧版本&#xff08;7、8四个文件都加载&#xff09;和新版本&#xff08;9只加载两个etc&#xff09;不一样&#xff0c;所以su - 现在要永久生效在…...

CentOS系统环境搭建(十三)——CentOS7安装nvm

centos系统环境搭建专栏&#x1f517;点击跳转 CentOS7.9安装nvm 文章目录 CentOS7.9安装nvm1.安装2.刷新系统环境3.查看所有node4.安装Node.js版本5.查看已安装版本号6.使用指定版本7.设置默认版本8.验证 在我们的日常开发中经常会遇到这种情况&#xff1a;手上有好几个项目&…...

uniapp评论列表插件获取

从评论列表&#xff0c;回复&#xff0c;点赞&#xff0c;删除&#xff0c;留言板 - DCloud 插件市场里导入&#xff0c;并使用。 代码样式优化及接入如下&#xff1a; <template><view class"hb-comment"><!-- 阅读数-start --><view v-if&q…...

3.redis数据结构之List

List-列表类型:L&R 列表类型&#xff1a;有序、可重复 Arraylist和linkedlist的区别 Arraylist是使用数组来存储数据&#xff0c;特点&#xff1a;查询快、增删慢 Linkedlist是使用双向链表存储数据&#xff0c;特点&#xff1a;增删快、查询慢&#xff0c;但是查询链表两端…...

安装使用MySQL8遇到的问题记录

1、root密码 启动运行后 /var/log/mysqld.log 存在默认密码 2023-08-21T15:58:17.469516Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.34) initializing of server in progress as process 61233 2023-08-21T15:58:17.478009Z 1 [System] [MY-013576] [I…...

Mysql、Oracle 中锁表问题解决办法

MySQL中锁表问题的解决方法&#xff1a; 1. 确定锁定表的原因&#xff1a; 首先&#xff0c;需要确定是什么原因导致了表的锁定。可能的原因包括长时间的事务、大量的并发查询、表维护操作等。 2. 查看锁定信息&#xff1a; 使用以下命令可以查看当前MySQL数据库中的锁定信…...

AUTOSAR规范与ECU软件开发(实践篇)5.1 ETAS ISOLAR-A工具简介

前言 如前所述, 开发者可以先在系统级设计工具ISOLAR-A中设计软件组件框架, 包括端口接口、 端口等, 即创建各软件组件arxml描述性文件; 再将这些软件组件描述性文件导入到行为建模工具, 如Matlab/Simulink中完成内部行为建模。 亦可以先在行为建模工具中完成逻辑建模, 再…...

shell脚本——expect脚本免交互

目录 一.Here Document 1.1.定义 1.2.多行重定向 二.expect实现免交互 2.1.基础免交互改密码 2.2.expect定义 2.3.expect基本命令 2.4.expect实现免交互ssh主机 一.Here Document 1.1.定义 使用I/O重定向的方式将命令列表提供给交互式程序&#xff0c;是标准输 入的一…...

ubuntu18.04安装远程控制软件ToDest方法,针对官网指令报错情况

有时我们在家办公&#xff0c;需要控制实验室的笔记本&#xff0c;因此好用的远程控制软件会让我们的工作事半功倍&#xff01; 常用的远程控制软件有ToDesk&#xff0c;向日葵&#xff0c;以及TeamViewer&#xff0c;但是为感觉ToDesk更流畅一些&#xff0c;所以这里介绍一下…...

系统架构设计师之缓存技术:Redis持久化的两种方式-RDB和AOF

系统架构设计师之缓存技术&#xff1a;Redis持久化的两种方式-RDB和AOF...

以创新点亮前路,戴尔科技开辟数实融合新格局

编辑&#xff1a;阿冒 设计&#xff1a;沐由 2023年&#xff0c;对于戴尔科技而言是特殊的一年&#xff0c;这是戴尔科技进入中国市场第25个年头——“巧合”的是&#xff0c;这25年也是中国产业经济发展最快&#xff0c;人们工作与生活发生变化最大的四分之一个世纪。 2023年&…...

使用Pandas处理Excel文件

Excel工作表是非常本能和用户友好的&#xff0c;这使得它们非常适合操作大型数据集&#xff0c;即使是技术人员也不例外。如果您正在寻找学习使用Python在Excel文件中操作和自动化内容的地方&#xff0c;请不要再找了。你来对地方了。 在本文中&#xff0c;您将学习如何使用Pan…...

设计模式——接口隔离原则

文章目录 基本介绍应用实例应传统方法的问题和使用接口隔离原则改进 基本介绍 客户端不应该依赖它不需要的接口&#xff0c;即一个类对另一个类的依赖应该建立在最小的接口上先看一张图: 类 A 通过接口 Interface1 依赖类 B&#xff0c;类 C 通过接口 Interface1 依赖类 D&…...

黑客(网络安全)自学

想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全…...

《Go 语言第一课》课程学习笔记(三)

构建模式&#xff1a;Go 是怎么解决包依赖管理问题的&#xff1f; Go 项目的布局标准是什么&#xff1f; 首先&#xff0c;对于以生产可执行程序为目的的 Go 项目&#xff0c;它的典型项目结构分为五部分&#xff1a; 放在项目顶层的 Go Module 相关文件&#xff0c;包括 go.…...

PSP - 基于开源框架 OpenFold Multimer 蛋白质复合物的结构预测与BugFix

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132410296 AlphaFold2-Multimer 是一个基于 AlphaFold2 的神经网络模型&#xff0c;可以预测多链蛋白复合物的结构。该模型在训练和推理时都可以处…...

Java课题笔记~ MyBatis分页查询插件

1.添加依赖 <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper --> <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.2.0</version> </de…...

(嵌入式c语言)类型修饰符

类型修饰符 对内存资源存储位置的限定 auto 默认的类型修饰符 修饰的变量可读可写 register 因为你内部寄存器比较少&#xff0c;使用此类型修饰符&#xff0c;会告诉编译器尽量把此数据放到寄存器。 CPU内部寄存器是编号来定义&#xff0c;无地址编号&#xff0c;所以r…...

1、Spring底层核心原理解析

1.入门案例 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); UserService userService = (UserService) context.getBean("userService"); userService.test(); 对于这三行代码应该,大部分同学应该都是比…...

迷路的机器人(递归回溯+动态规划两个方法实现)

题目&#xff1a; 设想有个机器人坐在一个网格的左上角&#xff0c;网格 r 行 c 列。机器人只能向下或向右移动&#xff0c;但不能走到一些被禁止的网格&#xff08;有障碍物&#xff09;。设计一种算法&#xff0c;寻找机器人从左上角移动到右下角的路径。 示例&#xff1a;…...

Nacos

Nacos介绍 Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的⾸字⺟简称&#xff0c;⼀个更易于构 建云原⽣应⽤的动态服务发现、配置管理和服务管理平台。 在这个介绍中&#xff0c;可以看出Nacos⾄少有三个核⼼功能&#xff1a; 1. 动态服务发现 2. 配…...

【Linux】网络层协议:IP

我们必须接受批评&#xff0c;因为它可以帮助我们走出自恋的幻象&#xff0c;不至于长久在道德和智识上自我陶醉&#xff0c;在自恋中走向毁灭&#xff0c;事实上我们远比自己想象的更伪善和幽暗。 文章目录 一、IP和TCP之间的关系&#xff08;提供策略 和 提供能力&#xff09…...

神经网络为什么可以学习

本资料转载于B站up主&#xff1a;大模型成长之路,仅用于学习和讨论&#xff0c;如有侵权请联系 动画解析神经网络为什么可以学习_哔哩哔哩_bilibilis 1、一个神经网络是由很多神经元形成的 1.1 也可以是一层&#xff0c;也可以是多层 2 层和层之间的连接就跟一张网一样 2.1 每…...

Docker基础入门:镜像、容器导入导出与私有仓库搭建

Docker基础入门&#xff1a;镜像导入导出与私有仓库搭建 一、 Docker镜像、容器的导入和导出1.1、Docker镜像的导出1.2、Docker镜像的载入1.3、Docker容器的导出1.4、Docker容器的导入 二、 镜像和容器导出和导入的区别:三、commit操作_本地镜像发布到阿里云3.1、commit操作有关…...

Go语言入门指南:基础语法和常用特性解析(上)

一、Go语言前言 Go是一种静态类型的编译语言&#xff0c;常常被称作是21世纪的C语言。Go语言是一个开源项目&#xff0c;可以免费获取编译器、库、配套工具的源代码&#xff0c;也是高性能服务器和应用程序的热门选择。 Go语言可以运行在类UNIX系统——比如Linux、OpenBSD、M…...

排序算法合集

F B I W a r n i n g : \color{red}FBI \qquad Warning: FBIWarning: 本人没有完整的计算机科班的教育经历&#xff0c;但是一直在兢兢业业&#xff0c;努力学习。 这些排序函数都是自己零零散散写的&#xff0c;也没有经过深思熟虑和优化&#xff0c;纯粹是为了自娱自乐。 …...

Vue2-全局事件总线、消息的订阅与发布、TodoList的编辑功能、$nextTick、动画与过渡

&#x1f954;&#xff1a;高度自律即自由 更多Vue知识请点击——Vue.js VUE2-Day9 全局事件总线1、安装全局事件总线2、使用事件总线&#xff08;1&#xff09;接收数据&#xff08;2&#xff09;提供数据&#xff08;3&#xff09;组件销毁前最好解绑 3、TodoList中的孙传父&…...

DP读书:鲲鹏处理器 架构与编程(八)3.1鲲鹏处理器片上系统与Taishan处理器内核架构

鲲鹏处理器片上系统架构 一、鲲鹏处理器片上系统与Taishan处理器内核架构1. 鲲鹏处理器片上系统概况a. 鲲鹏处理器片上系统与鲲鹏芯片家族b. 鲲鹏920处理器片上系统的组成部件c. 鲲鹏920处理器片上系统的特征d. 鲲鹏920处理器片上系统的逻辑结构 2. Taishan V110 处理器内核微架…...

如何使用 HOOPS Exchange SDK 和 Polygonica Bridge

这里将讨论使用 HOOPS Exchange 和 Polygonica 以及它们之间的桥梁进行 CAD 访问和网格处理。--提供Crack HOOPS 全系列SDK HOOPS Exchange 基础知识 首先&#xff0c;让我们简单回顾一下 HOOPS Exchange。HOOPS Exchange 是一款具有 C 接口的数据访问 SDK&#xff0c;支持导入…...

spring异步框架使用教程

背景 在需求开发过程中&#xff0c;为了提升效率&#xff0c;很容易就会遇到需要使用多线程的场景。这个时候一般都会选择建一个线程池去专门用来进行某一类动作&#xff0c;这种任务到来的时候往往伴随着大量的线程被创建调用。而还有另外一种场景是整个任务的执行耗时比较长…...

【数学建模】清风数模正课3 插值算法

插值算法 在数模比赛中&#xff0c;很多类型的题目都需要根据已知的函数点进行数据分析和模型处理&#xff1b; 当此时题目所给的数据较少时&#xff0c;我们就无法进行准确科学的分析&#xff0c;所以需要更多的数据&#xff0c;也就是函数点&#xff1b; 这就需要使用数学…...

什么是eval()?eval是用来干什么的?

一、什么是eval()? eval() 是 JavaScript 中的一个全局函数&#xff0c;用于解析并执行传递给它的字符串作为 JavaScript 代码。 二、eval()是用来干什么的&#xff1f; 当调用 eval() 时&#xff0c;它会将传入的字符串参数视为 JavaScript 代码&#xff0c;并在调用位置执…...

JavaScript-console:JavaScript控制台(Console)常用方法

一、理解 console JavaScript 控制台&#xff08;console&#xff09;是一个开发人员在编写 JavaScript 代码时常用的工具。它是浏览器提供的一种界面&#xff0c;让开发人员能够追踪代码执行的状态和结果。JavaScript 控制台可以记录代码输出的信息、警告和错误&#xff0c;并…...

Nginx配置前后端分离

后端地址 1.本地环境 curl --request GET \--url http://localhost:8080/by-admin/captchaImage \--header Authorization: Bearer d7a035d9-b30c-4ca5-8951-8cec90607943确认后端 ip 端口 上下文 2.测试环境 部署到测试环境可能是 换成内网ip和内网服务端口(ip、端口 可能会…...

rabbitmq的发布确认

生产者将信道设置成 confirm 模式&#xff0c;一旦信道进入 confirm 模式&#xff0c; 所有在该信道上面发布的 消息都将会被指派一个唯一的 ID (从 1 开始)&#xff0c;一旦消息被投递到所有匹配的队列之后&#xff0c;broker 就会发送一个确认给生产者(包含消息的唯一 ID)&…...

RISC-V公测平台发布· CoreMark测试报告

一. CoreMark简介 CoreMark是一款用于评估CPU性能的基准测试程序&#xff0c;它包含了多种不同的计算任务&#xff0c;包括浮点数、整数、缓存、内存等方面的测试。CoreMark的测试结果通常被用来作为CPU性能的参考&#xff0c;它可以帮助开发人员和系统管理员评估不同处理器和…...

模型微调(fine-tune)

一、关于模型微调的一些基础知识 1、模型微调&#xff08;fine-tune&#xff09; 微调(fine-tune)通过使用在大数据上得到的预训练好的模型来初始化自己的模型权重&#xff0c;从而提升精度。这就要求预训练模型质量要有保证。微调通常速度更快、精度更高。当然&#xff0c;自己…...

云农场种植:互联网+智慧牧场,为农业注入新的活力和创新

随着科技的不断发展&#xff0c;数字化农业正逐渐成为现代农业的趋势。传统农业面临着土地资源有限、劳动力不足等问题&#xff0c;而云农场种植模式通过数字化技术的运用&#xff0c;互联网养殖着重于“绿色、特色产品和智慧生态”&#xff0c;通过建立“线上养殖线下托养线上…...

Hadoop学习一(初识大数据)

目录 一 什么是大数据&#xff1f; 二 大数据特征 三 分布式计算 四 Hadoop是什么? 五 Hadoop发展及版本 六 为什么要使用Hadoop 七 Hadoop vs. RDBMS 八 Hadoop生态圈 九 Hadoop架构 一 什么是大数据&#xff1f; 大数据是指无法在一定时间内用常规软件工具对其内…...

linux定时备份MySQL数据库循环删除前30天的备份文件

linux定时备份MySQL数据库循环删除前30天的备份文件 一、 检查有没安装crond,如果没有&#xff0c;先安装 1、先检查一下有没有cron rpm -qa|grep cron如果输入上面命令有如下显示&#xff0c;则不需要安装 2、没有安装的话&#xff0c;就使用一下命令安装 yum -y install …...

不加电透明屏:在场景化应用中,有哪些特点和优点?

不加电透明屏是一种新型的显示技术&#xff0c;它可以在不需要电源的情况下显示图像和文字。 这种屏幕的原理是利用光的折射和反射来实现显示效果&#xff0c;而不需要通过电流来激发像素点。 不加电透明屏的最大优点是节能环保。传统的显示屏需要消耗大量的电能来显示图像&a…...

全球公链进展| Shibarium已上线;opBNB测试网PreContract硬分叉;Sui 主网 V1.7.1 版本

01 ETH 以太坊最新一次核心开发者执行会议&#xff1a;讨论 Devnet 8 更新、ElP-4788、Holesky 测试网等 以太坊核心开发者 Tim Beiko 总结最新一次以太坊核心开发者执行会议&#xff08;ACDE&#xff09;&#xff0c;讨论内容包括 Devnet 8 更新、ElP-4788、Holesky 测试网、…...

CSS中的display属性有哪些值?它们的作用?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS display 属性的不同取值和作用1. block2. inline3. inline-block4. none5. flex6. grid7. table、table-row、table-cell8. list-item9. inline-table、table-caption、table-column 等 ⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#x…...

ELKstack-日志收集案例

由于实验环境限制&#xff0c;将 filebeat 和 logstash 部署在 tomcat-server-nodeX&#xff0c;将 redis 和 写 ES 集群的 logstash 部署在 redis-server&#xff0c;将 HAproxy 和 Keepalived 部署在 tomcat-server-nodeX。将 Kibana 部署在 ES 集群主机。 环境&#xff1a;…...

基于GPT-4和LangChain构建云端定制化PDF知识库AI聊天机器人

参考&#xff1a; GitHub - mayooear/gpt4-pdf-chatbot-langchain: GPT4 & LangChain Chatbot for large PDF docs 1.摘要&#xff1a; 使用新的GPT-4 api为多个大型PDF文件构建chatGPT聊天机器人。 使用的技术栈包括LangChain, Pinecone, Typescript, Openai和Next.js…...