Aerospike:如果列表不存在,则自动创建一个列表并将项目附加到该列表
Aerospike: atomically create a list if it does not exists and append items to this list
aerospike 中的 bin 是 Map[String -> List]
我正在尝试实现这样的行为:
bin.computeIfAbsent(key, k -> new List()).addAll(itemsToAdd)
有没有一种方法可以在 Aerospike 中以原子方式执行此操作而无需实现 UDF?
如果我正确阅读文档,如果它是 Map[String -> Map]
,我可以使用 CTX.mapKeyCreate
按需创建内部地图,但我没有看到任何类似的创建列表
UPD:
这是我想要做的
我有一串三胞胎:
{"pk","attr","value"}
我需要将此流汇入由 pk
和 attr
聚合的 aerospike 集合,格式如下:
{
"PK":"pk",
"mapBin": {
"attr": ["value"]
}
}
假设流中有三个项目:{"pk","attr1","value1"},{"pk","attr2","value2"},{"pk","attr1","value3"}
他们需要这样降落在气钉上:
{
"PK":"pk",
"mapBin": {
"attr1": ["value1","value3"],
"attr2": ["value2"]
}
}
要插入新项目{"pk","attr2","value2"}
我需要执行几个操作:
- 在
mapBin[attr2]
获取列表
- 如果不存在,则将空列表插入映射
- 执行
ListOperation.append
将项目附加到现有列表
问题是:有没有办法在没有 UDF 的情况下自动完成?
您应该能够使用以下(Java 语法)自动执行这些操作:
record = client.operate(null, pk,
ListOperation.append("mapBin", Value.get("value2"),
CTX.mapKeyCreate(Value.get("attr2"),
MapOrder.UNORDERED)));
如果有多个项目要追加到一个列表中,您可以使用ListOperation.appendItems(),并且在同一个operate()中对映射中的不同列表进行多个ListOperations,所有这些都将自动执行.
我测试了上面@asnozzle提供的方案。 (服务器 5.7.0.11,Java 客户端 5.1.11)。 (我把 PK:pk 作为 k:v 放在 mapBin 中。我想你想要它在它自己的 bin 中。)
package com.aerospike;
import com.aerospike.client.*;
import com.aerospike.client.policy.WritePolicy;
import com.aerospike.client.cdt.MapPolicy;
import com.aerospike.client.cdt.CTX;
import com.aerospike.client.cdt.MapReturnType;
import com.aerospike.client.cdt.MapOrder;
import com.aerospike.client.cdt.ListOperation;
import com.aerospike.client.cdt.MapOperation;
public class TestExample {
public static void main(String[] args) throws Exception {
TestExample ce = new TestExample();
ce.runExample();
return;
}
public void runExample() throws Exception {
AerospikeClient client = new AerospikeClient("127.0.0.1", 3000);
insertTuple(client, "pk", "attr1", "a1v1");
insertTuple(client, "pk", "attr1", "a1v2");
insertTuple(client, "pk", "attr2", "a2v1");
insertTuple(client, "pk", "attr2", "a2v2");
insertTuple(client, "pk", "attr2", "a2v3");
insertTuple(client, "pk", "attr3", "a3v1");
}
private void insertTuple(AerospikeClient client, String s1, String s2, String s3) throws Exception {
Key key = new Key("test", "testset", "k1");
Record record = client.get(null, key);
System.out.println("\nInitial Record: " + record);
// Insert tuple data
WritePolicy wPolicy = new WritePolicy(client.writePolicyDefault);
MapPolicy mPolicy = new MapPolicy();
client.operate(wPolicy, key,
MapOperation.put(mPolicy, "mapBin", Value.get("PK"), Value.get(s1)),
ListOperation.append("mapBin", Value.get(s3), CTX.mapKeyCreate(Value.get(s2), MapOrder.UNORDERED))
);
record = client.get(null,key);
System.out.println("Get Record: " + record);
}
}
输出为:
Initial Record: null
Get Record: (gen:1),(exp:386490396),(bins:(mapBin:{attr1=[a1v1], PK=pk}))
Initial Record: (gen:1),(exp:386490396),(bins:(mapBin:{attr1=[a1v1], PK=pk}))
Get Record: (gen:2),(exp:386490396),(bins:(mapBin:{attr1=[a1v1, a1v2], PK=pk}))
Initial Record: (gen:2),(exp:386490396),(bins:(mapBin:{attr1=[a1v1, a1v2], PK=pk}))
Get Record: (gen:3),(exp:386490396),(bins:(mapBin:{attr2=[a2v1], attr1=[a1v1, a1v2], PK=pk}))
Initial Record: (gen:3),(exp:386490396),(bins:(mapBin:{attr2=[a2v1], attr1=[a1v1, a1v2], PK=pk}))
Get Record: (gen:4),(exp:386490396),(bins:(mapBin:{attr2=[a2v1, a2v2], attr1=[a1v1, a1v2], PK=pk}))
Initial Record: (gen:4),(exp:386490396),(bins:(mapBin:{attr2=[a2v1, a2v2], attr1=[a1v1, a1v2], PK=pk}))
Get Record: (gen:5),(exp:386490396),(bins:(mapBin:{attr2=[a2v1, a2v2, a2v3], attr1=[a1v1, a1v2], PK=pk}))
Initial Record: (gen:5),(exp:386490396),(bins:(mapBin:{attr2=[a2v1, a2v2, a2v3], attr1=[a1v1, a1v2], PK=pk}))
Get Record: (gen:6),(exp:386490396),(bins:(mapBin:{PK=pk, attr2=[a2v1, a2v2, a2v3], attr1=[a1v1, a1v2], attr3=[a3v1]}))
aerospike 中的 bin 是 Map[String -> List]
我正在尝试实现这样的行为:
bin.computeIfAbsent(key, k -> new List()).addAll(itemsToAdd)
有没有一种方法可以在 Aerospike 中以原子方式执行此操作而无需实现 UDF?
如果我正确阅读文档,如果它是 Map[String -> Map]
,我可以使用 CTX.mapKeyCreate
按需创建内部地图,但我没有看到任何类似的创建列表
UPD: 这是我想要做的
我有一串三胞胎:
{"pk","attr","value"}
我需要将此流汇入由 pk
和 attr
聚合的 aerospike 集合,格式如下:
{
"PK":"pk",
"mapBin": {
"attr": ["value"]
}
}
假设流中有三个项目:{"pk","attr1","value1"},{"pk","attr2","value2"},{"pk","attr1","value3"}
他们需要这样降落在气钉上:
{
"PK":"pk",
"mapBin": {
"attr1": ["value1","value3"],
"attr2": ["value2"]
}
}
要插入新项目{"pk","attr2","value2"}
我需要执行几个操作:
- 在
mapBin[attr2]
获取列表
- 如果不存在,则将空列表插入映射
- 执行
ListOperation.append
将项目附加到现有列表
问题是:有没有办法在没有 UDF 的情况下自动完成?
您应该能够使用以下(Java 语法)自动执行这些操作:
record = client.operate(null, pk,
ListOperation.append("mapBin", Value.get("value2"),
CTX.mapKeyCreate(Value.get("attr2"),
MapOrder.UNORDERED)));
如果有多个项目要追加到一个列表中,您可以使用ListOperation.appendItems(),并且在同一个operate()中对映射中的不同列表进行多个ListOperations,所有这些都将自动执行.
我测试了上面@asnozzle提供的方案。 (服务器 5.7.0.11,Java 客户端 5.1.11)。 (我把 PK:pk 作为 k:v 放在 mapBin 中。我想你想要它在它自己的 bin 中。)
package com.aerospike;
import com.aerospike.client.*;
import com.aerospike.client.policy.WritePolicy;
import com.aerospike.client.cdt.MapPolicy;
import com.aerospike.client.cdt.CTX;
import com.aerospike.client.cdt.MapReturnType;
import com.aerospike.client.cdt.MapOrder;
import com.aerospike.client.cdt.ListOperation;
import com.aerospike.client.cdt.MapOperation;
public class TestExample {
public static void main(String[] args) throws Exception {
TestExample ce = new TestExample();
ce.runExample();
return;
}
public void runExample() throws Exception {
AerospikeClient client = new AerospikeClient("127.0.0.1", 3000);
insertTuple(client, "pk", "attr1", "a1v1");
insertTuple(client, "pk", "attr1", "a1v2");
insertTuple(client, "pk", "attr2", "a2v1");
insertTuple(client, "pk", "attr2", "a2v2");
insertTuple(client, "pk", "attr2", "a2v3");
insertTuple(client, "pk", "attr3", "a3v1");
}
private void insertTuple(AerospikeClient client, String s1, String s2, String s3) throws Exception {
Key key = new Key("test", "testset", "k1");
Record record = client.get(null, key);
System.out.println("\nInitial Record: " + record);
// Insert tuple data
WritePolicy wPolicy = new WritePolicy(client.writePolicyDefault);
MapPolicy mPolicy = new MapPolicy();
client.operate(wPolicy, key,
MapOperation.put(mPolicy, "mapBin", Value.get("PK"), Value.get(s1)),
ListOperation.append("mapBin", Value.get(s3), CTX.mapKeyCreate(Value.get(s2), MapOrder.UNORDERED))
);
record = client.get(null,key);
System.out.println("Get Record: " + record);
}
}
输出为:
Initial Record: null
Get Record: (gen:1),(exp:386490396),(bins:(mapBin:{attr1=[a1v1], PK=pk}))
Initial Record: (gen:1),(exp:386490396),(bins:(mapBin:{attr1=[a1v1], PK=pk}))
Get Record: (gen:2),(exp:386490396),(bins:(mapBin:{attr1=[a1v1, a1v2], PK=pk}))
Initial Record: (gen:2),(exp:386490396),(bins:(mapBin:{attr1=[a1v1, a1v2], PK=pk}))
Get Record: (gen:3),(exp:386490396),(bins:(mapBin:{attr2=[a2v1], attr1=[a1v1, a1v2], PK=pk}))
Initial Record: (gen:3),(exp:386490396),(bins:(mapBin:{attr2=[a2v1], attr1=[a1v1, a1v2], PK=pk}))
Get Record: (gen:4),(exp:386490396),(bins:(mapBin:{attr2=[a2v1, a2v2], attr1=[a1v1, a1v2], PK=pk}))
Initial Record: (gen:4),(exp:386490396),(bins:(mapBin:{attr2=[a2v1, a2v2], attr1=[a1v1, a1v2], PK=pk}))
Get Record: (gen:5),(exp:386490396),(bins:(mapBin:{attr2=[a2v1, a2v2, a2v3], attr1=[a1v1, a1v2], PK=pk}))
Initial Record: (gen:5),(exp:386490396),(bins:(mapBin:{attr2=[a2v1, a2v2, a2v3], attr1=[a1v1, a1v2], PK=pk}))
Get Record: (gen:6),(exp:386490396),(bins:(mapBin:{PK=pk, attr2=[a2v1, a2v2, a2v3], attr1=[a1v1, a1v2], attr3=[a3v1]}))