Android Database - first and fast, lightweight on-device vector database
APACHE-2.0 License
Bot releases are hidden (Show)
Box.query()
, it is still useful for queries without any condition.QueryBuilder
that they are not recommended for new projects. Use the new query APIs instead.ToOne
and ToMany
.Published by greenrobot-team 5 months ago
ObjectBox now supports Vector Search to enable efficient similarity searches.
This is particularly useful for AI/ML/RAG applications, e.g. image, audio, or text similarity. Other
use cases include semantic search or recommendation engines.
Create a Vector (HNSW) index for a floating point vector property. For example, a City
with a
location vector:
@Entity
public class City {
@HnswIndex(dimensions = 2)
float[] location;
}
Perform a nearest neighbor search using the new nearestNeighborsF32(queryVector, maxResultCount)
query condition and the new "find with scores" query methods (the score is the distance to the
query vector). For example, find the 2 closest cities:
final float[] madrid = {40.416775F, -3.703790F};
final Query<City> query = box
.query(City_.location.nearestNeighbors(madrid, 2))
.build();
final City closest = query.findWithScores().get(0).get();
For an introduction to Vector Search, more details and other supported languages see the
Vector Search documentation.
Store.sizeOnDisk()
. Instead use one of the new APIs to determine the size of a database:
Store.getDbSize()
which for a file-based database returns the file size and for an in-memory database returns the approximately used memory,Store.getDbSizeOnDisk()
which only returns a non-zero size for a file-based database.setParameter(prop, value)
methods that only accept a single parameter value, deprecated the old setParameters(prop, value)
variants.SyncCredentials.userAndPassword(user, password)
.Published by greenrobot-team 8 months ago
inMemory()
when building a BoxStore
:
store = MyObjectBox.builder()
.androidContext(context)
.inMemory("test-db")
.build();
See the BoxStoreBuilder.inMemory()
documentation for details.BoxStore.deleteAllFiles()
to support deleting an in-memory database.maxDataSizeInKByte()
option when building a store is ready for production use. This is different from the existing maxSizeInKByte()
option in that it is possible to remove data after reaching the limit and continue to use the database. See its documentation for more details.kotlin-stdlib
1.8 from objectbox-kotlin
as it includes classes previously in the -jdk7/-jdk8 libraries to avoid duplicate class file errors. So if not absolutely needed, we still recommend to use at least Kotlin 1.8.validateOnOpenKv()
is available on MyObjectBox.builder()
to help diagnose FileCorruptException: Corrupt DB, min key size violated
issues. If enabled, the build()
call will throw a FileCorruptException
if corruption is detected with details on which key/value is affected. #1143
__cxa_pure_virtual
crash should not occur anymore; if you get related exceptions, they should contain additional information to better diagnose this issue. Let us know details in #1131
VALUE
. Reported via objectbox-dart#318
config
package:
io.objectbox.DebugFlags
is deprecated, use io.objectbox.config.DebugFlags
instead.io.objectbox.model.ValidateOnOpenMode
is deprecated, use io.objectbox.config.ValidateOnOpenModePages
instead.Published by greenrobot-team over 1 year ago
Support for integer and floating point arrays: store
short[]
, char[]
, int[]
, long[]
andfloat[]
and double[]
(or their Kotlin counterparts, e.g. FloatArray
) without a converter.
A simple example is a shape entity that stores a palette of RGB colors:
@Entity
public class Shape {
@Id public long id;
// An array of RGB color values that are used by this shape.
public int[] palette;
}
// Find all shapes that use red in their palette
try (Query<Shape> query = store.boxFor(Shape.class)
.query(Shape_.palette.equal(0xFF0000))
.build()) {
query.findIds();
}
This can also be useful to store vector embeddings produced by machine learning, e.g.:
@Entity
public class ImageEmbedding {
@Id public long id;
// Link to the actual image, e.g. on Cloud storage
public String url;
// The coordinates computed for this image (vector embedding)
public float[] coordinates;
}
Fix incorrect Cursor code getting generated when using @Convert
to convert to a String
array.
The io.objectbox.sync
plugin now also automatically adds a Sync-enabled JNI library on macOS and Windows (previously on Linux x64 only; still need to add manually for Linux on ARM).
We're hiring! 😎 We believe resource-efficient coding is still cool and are looking for a C / C++ developer who shares our sentiment.
Published by greenrobot-team over 1 year ago
DbSchemaException
on how to resolve its typical causes.We're hiring! 😎 We believe resource-efficient coding is still cool and are looking for a C / C++ developer who shares our sentiment.
Published by greenrobot-team almost 2 years ago
This release includes breaking changes to generated code. If you encounter build errors, make sure to clean and build your project (e.g. Build > Rebuild project in Android Studio).
Query.copy()
and QueryThreadLocal
to obtain a Query
instance to use in different threads. Learn more about re-using queries. #1071relationCount
query condition to match objects that have a certain number of related objects pointing to them. E.g. Customer_.orders.relationCount(2)
will match all customers with two orders, Customer_.orders.relationCount(0)
will match all customers with no associated order. This can be useful to find objects where the relation was dissolved, e.g. after the related object was removed.query.property(Order_.customerId)
will map results to the ID of the customer of an order. #1028DbFullException
about why it occurs and how to handle it.Using Sync? This release uses a new Sync protocol which improves efficiency. Reach out via your existing contact to check if any actions are required for your setup.
Published by greenrobot-team about 2 years ago
findFirstId()
and findUniqueId()
to Query
which just return the ID of a matching object instead of the full object.maxDataSizeInKByte
property when building a Store. This is different from the existing maxSizeInKByte
property in that it is possible to remove data after reaching the limit and continue to use the database. See its documentation for more details.@Index(type = IndexType.VALUE)
) on Android 32-bit ARM devices. #1105Using Sync? There is no Sync version for this release, please continue using version 3.2.1.
Note: V3.3.0 contains a bug preventing correct transformation of some classes, please use V3.3.1 instead.
Using Sync? There is no Sync version for this release, please continue using version 3.2.1.
Published by greenrobot-team over 2 years ago
IllegalStateException
when query is closed instead of crashing the virtual machine. #1081IllegalStateException
when trying to subscribe but the store or query is closed already.Published by greenrobot-team over 2 years ago
ToOne
instead of ToOne<Entity>
).AndroidObjectBrowser
, use Admin
instead. AndroidObjectBrowser
will be removed in a future release.This release only contains bug fixes for the Android library when used with ObjectBox for Dart/Flutter.
Published by greenrobot-team over 2 years ago
This release only contains bug fixes.
localhost:8090
and localhost:8091
).Published by greenrobot-team almost 3 years ago
Read the blog post with more details and code examples for the new flex properties and query conditions.
3.0.0
, it is now possible to add a property using Object
in Java or Any?
in Kotlin. These "flex properties" now allow to store values of various types like integers, floating point values, strings and byte arrays. Or lists and maps (using string keys) of those. Some limitations apply, see the FlexObjectConverter
class documentation for details.
@Entity
data class Customer(
@Id var id: Long = 0,
var tag: Any? = null
)
val customerStrTag = Customer(tag = "string-tag")
val customerIntTag = Customer(tag = 1234)
box.put(customerStrTag, customerIntTag)
containsElement
query condition now matches keys of string map properties. It also matches string or integer elements of a Flex list.containsKeyValue
query condition to match key/value combinations of string map and Flex map properties containing strings and integers. Also added matching Query.setParameters
overload.
val customer = Customer(
properties = mutableMapOf("premium" to "tier-1")
)
box.put(customer)
// Query for any customers that have a premium key in their properties map
val queryPremiumAll = box.query(
Customer_.properties.containsElement("premium")
).build()
// Match only customers with specific key and value map entry
val queryPremiumTier1 = box.query(
Customer_.properties.containsKeyValue("premium", "tier-1")
).build()
SuppressFBWarnings
annotation. #1011BoxStore.awaitCallInTx
suspend function which wraps BoxStore.callInTx
.application
plugin.See the 3.0.0 release notes for a list of important changes.
Published by greenrobot-team about 3 years ago
Note: this version contains a bug that prevents usage with Android Java only projects. Use 3.0.1
instead.
// equal AND (less OR oneOf)
val query = box.query(
User_.firstName equal "Joe"
and (User_.age less 12
or (User_.stamp oneOf longArrayOf(1012))))
.order(User_.age)
.build()
StringOrder
for which one to choose (typically StringOrder.CASE_INSENSITIVE
).
// Replace String conditions like
query().equal(User_.firstName, "Joe")
// With the one accepting a StringOrder
query().equal(User_.firstName, "Joe", StringOrder.CASE_INSENSITIVE)
@Entity
class is missing a no-arg (easy to add) or all properties (best for performance) constructor. #900@Entity
public class Order {
@Id
private long id;
private ToOne<Customer> customer;
private ToMany<Order> relatedOrders;
// All properties constructor for ObjectBox:
// - make sure type matches exactly,
// - for ToOne add its virtual ID property instead,
// - for ToMany add no parameter.
public Order(long id, long customerId) {
this.id = id;
this.customer.setTargetId(customerId);
}
// TODO getters and setters for properties
}
@Unique(onConflict = ConflictStrategy.REPLACE)
to replace an existing Object if a conflict occurs when doing a put. #509
@Entity
data class Example(
@Id
var id: Long = 0,
@Unique(onConflict = ConflictStrategy.REPLACE)
var uniqueKey: String? = null
)
@Unsigned
to indicate that values of an integer property (e.g. Integer
and Long
in Java) should be treated as unsigned when doing queries or creating indexes.@Type
annotation:
@Type(DatabaseType.DateNano)
var timeInNanos: Long;
Flow
extension functions for BoxStore
and Query
. #990NaN
value. #984String[]
and Kotlin Array<String>
) and lists (Java List<String>
and Kotlin MutableList<String>
). Using the new containsElement("item")
condition, it is also possible to query for entities where "item" is equal to one of the elements.
@Entity
data class Example(
@Id
var id: Long = 0,
var stringArray: Array<String>? = null,
var stringMap: MutableMap<String, String>? = null
)
// matches [“first”, “second”, “third”]
box.query(Example_.stringArray.containsElement(“second”)).build()
Map<String, String>
or Kotlin MutableMap<String, String>
). Stored internally as a byte array using FlexBuffers.Published by greenrobot-team over 3 years ago
This is the first release available on the Central repository (Sonatype OSSRH). Make sure to adjust your build.gradle
files accordingly:
repositories {
mavenCentral()
}
Changes:
find(offset, limit)
of Query
is more concrete on how offset and limit work.objectbox-android:2.9.0:sync
is replaced with objectbox-sync-android:2.9.1
.Published by greenrobot-team over 3 years ago
lessOrEqual
and greaterOrEqual
conditions for long, String, double and byte[] properties.implementation "io.objectbox:objectbox-linux-armv7:$objectboxVersion
or implementation "io.objectbox:objectbox-linux-arm64:$objectboxVersion
to your dependencies. Otherwise the setup is identical with Java Desktop Apps.ClassNotFoundException: kotlin.text.Charsets
when running processor. #946