If a database with IDs stored as strings is opened in version 4.3.2, old records can still be retrieved by ID using a "_id" on top level. However, if the "_id" filter is placed inside an OR (or AND) clause, no document will be returned for documents with string ID. The behavior can be reproduced by storing "_id" as string in a new file database.
Test "ID String search" passes while "OR ID search" fails.
private static Nitrite open(File file) {
NitriteBuilder builder = Nitrite.builder();
MVStoreModuleBuilder mvBuilder = MVStoreModule.withConfig().compress(true);
mvBuilder.filePath(file);
builder.loadModule(mvBuilder.build());
return builder.openOrCreate();
}
private void buildDb(File dbFile, Object...docIds) {
try (Nitrite dst = open(dbFile)) {
NitriteCollection to = dst.getCollection("my_table");
for (Object docId : docIds) {
Document copy = Document.createDocument();
copy.put("_id", docId);
to.insert(copy);
}
dst.commit();
}
}
@Test
public void testIdSearch() throws Exception {
File tempDb = File.createTempFile("temp_db-", ".db");
try {
buildDb(tempDb, "1840817122658033664", 2041406700293308416L);
try(Nitrite nitrite = open(tempDb)) {
NitriteCollection collection = nitrite.getCollection("my_table");
Filter idFilter1 = FluentFilter.where("_id").eq(2041406700293308416L);
Filter idFilter2 = FluentFilter.where("_id").eq(1840817122658033664L);
Set<Long> ids = new HashSet<>();
for (Document doc : collection.find(idFilter1).toList()) {
Long id = doc.getId().getIdValue();
ids.add(id);
}
for (Document doc : collection.find(idFilter2).toList()) {
Long id = doc.getId().getIdValue();
ids.add(id);
}
assertTrue("ID Long search", ids.contains(2041406700293308416L));
assertTrue("ID String search", ids.contains(1840817122658033664L));
Set<Long> orIds = new HashSet<>();
for (Document doc : collection.find(Filter.or(idFilter1, idFilter2)).toList()) {
Long id = doc.getId().getIdValue();
orIds.add(id);
}
assertTrue("OR ID Long search", orIds.contains(2041406700293308416L));
assertTrue("OR ID search", orIds.contains(1840817122658033664L));
}
} finally {
tempDb.delete();
}
}
If a database with IDs stored as strings is opened in version 4.3.2, old records can still be retrieved by ID using a "_id" on top level. However, if the "_id" filter is placed inside an OR (or AND) clause, no document will be returned for documents with string ID. The behavior can be reproduced by storing "_id" as string in a new file database.
Test "ID String search" passes while "OR ID search" fails.