Closed Aloren closed 7 years ago
Here is an explanation from our docs:
public Key(String namespace, String setName, int key) throws AerospikeException
Initialize key from namespace, optional set name and user key. The set name and user defined key are converted to a digest before sending to the server. The user key is not used or returned by the server by default. If the user key needs to persist on the server, use one of the following methods:
1) Set "WritePolicy.sendKey" to true. In this case, the key will be sent to the server for storage on writes and retrieved on multi-record scans and queries.
2) Explicitly store and retrieve the key in a bin.
Thanks. Could you please explain why it was done that way? For me it looks not obvious right now.
Some customers use long URLs for keys. They save bandwidth and storage when the key's hash digest (always 20 bytes) is sent instead of the key. Some applications use the key to uniquely identify a record only.
Ok. Thanks.
Hi,
I was trying to test how server behaves with multiple filters -- server responded that it now only supports only one filter, so I looked into aerospike-helper-java
how multiple filters are implemented there and created following test:
@Test
public void shouldFindByFirstNameAndAge() throws Exception {
IndexTask task = client.createIndex(null, info.getNamespace(),
"my-set", "firstName-index", "firstName", IndexType.STRING);
task.waitTillComplete();
IndexTask task2 = client.createIndex(null, info.getNamespace(),
"my-set", "age-index", "age", IndexType.NUMERIC);
task2.waitTillComplete();
WritePolicy policy = new WritePolicy();
policy.sendKey = true;
client.put(policy, new Key(info.getNamespace(), "my-set", "id-0"), new Bin("firstName", "Mykola"), new Bin("age", 45));
client.put(policy, new Key(info.getNamespace(), "my-set", "id-1"), new Bin("firstName", "Vasya"), new Bin("age", 15));
Statement statement = new Statement();
statement.setNamespace(info.getNamespace());
statement.setSetName("my-set");
statement.setFilters(Filter.range("age", 10, 20));
Map<String, Object> originArgs = new HashMap<>();
originArgs.put("includeAllFields", 1);
originArgs.put("filterFuncStr", "if rec['firstName'] == 'Vasya' then selectedRec = true end");
statement.setAggregateFunction(this.getClass().getClassLoader(), "as_utility.lua", "as_utility", "select_records", Value.get(originArgs));
QueryPolicy queryPolicy = new QueryPolicy();
queryPolicy.sendKey = true;
ResultSet records = client.queryAggregate(queryPolicy, statement);
Object foundRecord = records.iterator().next();
Assertions.assertThat(foundRecord).isNotNull();
}
As you can see I set property sendKey
to true for all operations, test succeeds, BUT I still am not able to find userKey
in foundRecord.
What I see in debugger:
Is the only option to get userKey is to save it as a bin for such case?
The result returned is not a Record type, but rather an Object type, most likely constructed by the map() function in the as_utility.lua function. It can be enhanced to include the record key in the object as well, using the record.key() function. See http://www.aerospike.com/docs/udf/api/record.html#functions
I have following test.
The last line fails with message:
After debugging I've found
MultiCommand
methodparseKey
. For my test it always executes with fieldcount = 3 and this code is never executed: