Is there a way to create an Index with @Index on the key of a map?
Index on map key
#1
#2
Indexes on map keys as well as queries on map keys are currently not supported.
But as a workaround you can use a collection of embedded objects, as demonstrated below:
package test; import java.util.*; import javax.jdo.annotations.Index; import javax.persistence.*; public class T1255 { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory( "objectdb:test.tmp;drop"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); for (int i = 0; i < 100000; i++) { MyEntry entry = new MyEntry("k" + i, "v" + i); em.persist(new MyEntity(Collections.singletonList(entry))); } em.getTransaction().commit(); em.close(); em = emf.createEntityManager(); long ms = System.currentTimeMillis(); Query query = em.createQuery( "SELECT o FROM MyEntity o JOIN o.map e WHERE e.key = 'k50000'"); List resultList = query.getResultList(); ms = System.currentTimeMillis() - ms; System.out.println("Result: " + resultList); System.out.println("Time: " + ms + "ms"); em.close(); emf.close(); } @Entity @Index(members={"map.key"}) public static class MyEntity { MyEntity(Collection<MyEntry> map) { this.map = map; } Collection<MyEntry> map; @Override public String toString() { return map.toString(); } } @Embeddable public static class MyEntry { String key; String value; public MyEntry(String key, String value) { this.key = key; this.value = value; } @Override public String toString() { return key + ":" + value; } } }
In this example, the field map is implemented as Collection<MyEntry>, i.e. a collection of a key-value embeddable objects.
An index on the key is defined using @Index(members={"map.key"}).
Running this example with and without the index definition shows that performance with index is better.
ObjectDB Support