我在文档中有一个字段是ipv4的字符串表示形式(“1.2.3.4”),该字段的名称是“originating_ip”。我正在尝试使用无痛语言的脚本字段,以便添加一个新字段(originating_ip_calc)以获得所述IPv4的int(长)表示形式。
下面的脚本在groovy中工作(从我的理解来看,这基本上应该是一样的),但似乎在这个特定的情况下几乎不是。
String[] ipAddressInArray = "1.2.3.4".split("\\.");
long result = 0;
for (int i = 0; i < ipAddressInArray.length; i++) {
int power = 3 - i;
int ip = Integer.parseInt(ipAddressInArray[i]);
long longIP = (ip * Math.pow(256, power)).toLong();
result = result + longIP;
}
return result;
我也在看这个问题,正如你从上面的代码中看到的那样,它是基于其中一个答案。
还尝试使用InetAddress,但没有运气。
使用Elasticsearch无痛脚本,您可以使用以下代码:
POST ip_search/doc/_search
{
"query": {
"match_all": {}
},
"script_fields": {
"originating_ip_calc": {
"script": {
"source": """
String ip_addr = params['_source']['originating_ip'];
def ip_chars = ip_addr.toCharArray();
int chars_len = ip_chars.length;
long result = 0;
int cur_power = 0;
int last_dot = chars_len;
for(int i = chars_len -1; i>=-1; i--) {
if (i == -1 || ip_chars[i] == (char) '.' ){
result += (Integer.parseInt(ip_addr.substring(i+ 1, last_dot)) * Math.pow(256, cur_power));
last_dot = i;
cur_power += 1;
}
}
return result
""",
"lang": "painless"
}
}
},
"_source": ["originating_ip"]
}
(请注意,我使用 Kibana 控制台将请求发送到 ES,它会在发送之前进行一些转义以使它成为有效的 JSON。
这将给出如下响应:
"hits": [
{
"_index": "ip_search",
"_type": "doc",
"_id": "2",
"_score": 1,
"_source": {
"originating_ip": "10.0.0.1"
},
"fields": {
"originating_ip_calc": [
167772161
]
}
},
{
"_index": "ip_search",
"_type": "doc",
"_id": "1",
"_score": 1,
"_source": {
"originating_ip": "1.2.3.4"
},
"fields": {
"originating_ip_calc": [
16909060
]
}
}
]
但是为什么一定要这样呢?
如果将问题中的代码发送到 ES,则会回复如下错误:
"script": "String[] ipAddressInArray = \"1.2.3.4\".split(\"\\\\.\");\n\nlong result = 0;\nfor (int i = 0; i < ipAddressInArray.length; i++) {\n int power = 3 - i;\n int ip = Integer.parseInt(ipAddressInArray[i]);\n long longIP = (ip * Math.pow(256, power)).toLong();\n result = result + longIP;\n}\nreturn result;",
"lang": "painless",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Unknown call [split] with [1] arguments on type [String]."
这主要是由于Java的<code>字符串。split()被认为不安全使用(因为它隐式创建正则表达式模式)。他们建议使用模式#split,但要做到这一点,您应该在索引中启用正则表达式。
默认情况下,它们被禁用:
"script": "String[] ipAddressInArray = /\\./.split(\"1.2.3.4\");...
"lang": "painless",
"caused_by": {
"type": "illegal_state_exception",
"reason": "Regexes are disabled. Set [script.painless.regex.enabled] to [true] in elasticsearch.yaml to allow them. Be careful though, regexes break out of Painless's protection against deep recursion and long loops."
因此,我们必须手动将字符串拆分为点。简单的方法是将字符串的每个字符与'.'
进行比较(Java表示char
文字,而不是String
)。
但是对于无痛
它意味着String
。所以我们必须对char
进行显式转换(因为我们正在迭代一个字符数组)。
因为显然< code >无痛不允许< code >。< code>String的length方法:
"reason": {
"type": "script_exception",
"reason": "compile error",
"script_stack": [
"\"1.2.3.4\".length",
" ^---- HERE"
],
"script": "\"1.2.3.4\".length",
"lang": "painless",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Unknown field [length] for type [String]."
}
}
虽然我在快速谷歌搜索后找不到任何关于命名的历史记录,但从留档页面和一些经验(如上所述),我可以推断出它被设计为在生产中使用无痛。
它的前身Groovy由于资源使用和安全漏洞而成为一颗定时炸弹。因此,Elasticsearch团队创建了一个非常有限的Java /Groovy脚本子集,它将具有可预测的性能并且不会包含这些安全漏洞,并将其称为无痛
。
如果说< code >无痛脚本语言有什么是真的,那就是它是有限的和沙箱化的。
问题内容: 我有一个使用long作为ID的定制类。但是,当我使用ajax调用操作时,我的ID被截断并且丢失了最后2个数字,因为javascript处理大数字时会失去精度。我的解决方案是给我的JavaScript字符串,但是ID必须在服务器端保留很长时间。 有没有一种方法可以将属性序列化为字符串?我在寻找某种属性。 控制者 模型 JSON结果 问题答案: 您可能可以创建一个自定义并将其应用于您的媒体
问题内容: 有没有一种方法可以将整数转换为PHP中的字符串? 问题答案: 您可以使用该函数将数字转换为字符串。 从维护的角度来看,它显然是您正在尝试做的事情,而不是其他一些更深奥的答案。当然,这取决于您的上下文。
我想有一个JPQL查询,它可能看起来像: 其中a.num是一个整数。我想将此转换为字符串以使用类似的条件。然而,上述转换在JPQL中不起作用。我该如何实现这一点?
我有一个,我希望将其转换为。在Java8之前,我会通过循环,将每个转换为并将其添加到新的,如下所示。
问题内容: 如何在JavaScript中将字符串转换为整数? 问题答案: 最简单的方法是使用本机函数: 如果这对您不起作用,则有 parseInt , 一元加号 , 带有floor的parseFloat 和 Math.round 方法。 parseInt: 一元加号,如果您的字符串已经是整数形式: 如果您的字符串是浮点数或可能是浮点数,并且您想要一个整数: 或者,如果您要多次使用Math.floo