I have two caches, one is for Person and another is for Company objects, By specifying the Person.Id as the key and Person.CompanyId as the affinity key.
personCache.Put(new AffinityKey(p1.Id, p1.CompanyId), p1);
companyCache.Put(c1.Id, c1);
Is it possible to get the person from the cache using Person.Id? (without having Person.CompanyId)?
Yes, but not with Key-Value API.
Key-Value API, by definition, requires a key to access the data. If your key is AffinityKey(personId, companyId)
then you have to construct the full key object in order to use the IgniteCache::get
operation.
However, there is also SQL API which is another interface to access the same data. You can declare the cache as an SQL-enabled cache and the personId
as an SQL field in that cache.
There are multiple ways to create an SQL-enabled cache:
Create it with the CREATE TABLE
statement (as opposed to specifying it in the node config or creating with the createCache
method).
Specify indexedTypes
as a part of the CacheConfiguration
and annotate the fields of the key and value objects as @QuerySqlField
.
The problem with indexedTypes
is that you have to put annotations into classes. Obviously, this is not going to work with AffinityKey
class, as you can't change it.
Specify QueryEntity
as a part of the CacheConfiguration
.
The problem with QueryEntity
is that it may get pretty complex, and it's generally a bit harder to maintain then @QuerySqlField
annotations.
In your case, I would recommend not to use AffinityKey
class and create your own version of it - let's call it PersonKey
. You can annotate its fields and use indexedTypes
.
Below is a short example:
public class SqlFieldInKeyExample {
static class PersonKey {
@QuerySqlField
long personId;
@QuerySqlField
@AffinityKeyMapped
long companyId;
public PersonKey(long personId, long companyId) {
this.personId = personId;
this.companyId = companyId;
}
}
static class Person {
@QuerySqlField
String name;
public Person(String name) {
this.name = name;
}
}
public static void main(String[] args) throws IgniteException {
try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
CacheConfiguration<PersonKey, Person> cfg = new CacheConfiguration<PersonKey, Person>()
.setName("PersonCache")
.setIndexedTypes(PersonKey.class, Person.class);
IgniteCache<PersonKey, Person> cache = ignite.createCache(cfg);
cache.put(new PersonKey(9000, 42), new Person("John Doe"));
List<List<?>> result = cache.query(new SqlFieldsQuery("SELECT * FROM PERSON WHERE PERSONID = 9000")).getAll();
assert result.size() == 1;
System.out.println(">>>>> Person: " + result.get(0));
}
}
}
Output (among other things) is:
>>>>> Person: [9000, 42, John Doe]