In the first part, we explored how to use ObjectBox with Flutter and location data to build a basic offline nearby search feature.
Now, let’s go a step further — and make it
smarter and faster using ObjectBox’s built-in nearestNeighbor()
vector search.
Don’t worry — no machine learning, embeddings, or complex math.
We’re
keeping it simple using
city coordinates (latitude + longitude) as float vectors!
📘 This is a follow-up blog post!
If you haven’t checked out the first part yet, start here: https://www.mobiledev.blog/2025/05/build-offline-find-nearby-places.html
🚀 What We’ll Do in This Follow-Up
We’ll show you how to:
✅ Store a list of cities as vector data
✅ Accept a user's current
location
✅ Find the top 3 closest cities using
nearestNeighbor()
✅ All of it works
fully offline, in milliseconds ⚡
🛠 Why Vector Search?
Our First blog traditional filtering is like:
Show cities where distance < 100km.
But nearestNeighbor()
lets us say:
Just give me the closest ones, I don’t care how far.
This removes guesswork (thresholds), makes your code cleaner, and improves UX.
While ObjectBox finds the nearest neighbors, we still need to calculate the actual distances to display to users:
Why Offline Nearby Search Matters
While online APIs like Google Places are powerful, they have limitations:
- Connectivity requirements: Users in areas with poor connectivity can't access location data
- API costs: Location service APIs often charge per request
- Privacy concerns: Some applications need to function without sending location data to external servers
By implementing offline nearby search, you can provide a seamless experience regardless of connectivity while potentially reducing costs and enhancing privacy.
Understanding ObjectBox's Nearest Neighbor Feature
ObjectBox is a super-fast NoSQL database that works great with Flutter. One of its most powerful features for location-based apps is the nearest neighbor query capability.
The nearest neighbor algorithm efficiently finds the closest points in a multidimensional space. For location data, this means finding places closest to a given latitude and longitude without having to calculate distances for every single place in your database.
Follow the setup instructions in this blog to add ObjectBox DB dependencies to your Flutter project. https://www.mobiledev.blog/2025/05/build-offline-find-nearby-places.html
📦 Step 1: Define Your City Model
@Entity()
class Place {
int id = 0;
String name;
@Property(type: PropertyType.floatVector)
@HnswIndex(dimensions: 2, distanceType: VectorDistanceType.geo)
List<double> locationVector;
Place(this.name, this.locationVector);
}
📌 Breaking It Down: What Does This Line Do?
This line is at the heart of how ObjectBox enables fast vector search in your Flutter app — particularly when dealing with location data like latitude and longitude.
Let’s explore each annotation:
🔢 @Property(type: PropertyType.floatVector)
This tells ObjectBox:
I want to store a vector (a list of floating-point numbers) in the database.
In our case, we’re using:
List<double> locationVector = [latitude, longitude];
This allows ObjectBox to treat this field as multi-dimensional numeric data, perfect for similarity search or spatial queries.
🚀 @HnswIndex(dimensions: 2, distanceType: VectorDistanceType.geo)
Now this is where things get cool.
HNSW stands for Hierarchical Navigable Small World — it's a graph-based algorithm used for Approximate Nearest Neighbor (ANN) search.
This annotation enables HNSW indexing, the secret sauce behind blazing-fast nearest-neighbor queries. Here's what each parameter means:
🌆 Step 2: Add Sample Cities
add a few cities in db:
final docsDir = await getApplicationDocumentsDirectory();
final Store store = await openStore(directory: "${docsDir.path}/nearby_places_example/");
final placeBox = store.box<Place>();
final places = [
Place("Mumbai", [19.0760, 72.8777]),
Place("Delhi", [28.6139, 77.2090]),
Place("Chennai", [13.0827, 80.2707]),
Place("Kolkata", [22.5726, 88.3639]),
Place("Bengaluru", [12.9716, 77.5946]),
];
placeBox.putMany(places);
store.close();
📍 Step 3: Get User Location - Mocking for now.
final currentLocation = [13.05, 80.25]; // near Chennai
🔍 Step 4: Use nearestNeighbor()
to Find Closest Cities
final currentLocation = [13.05, 80.25]; // near Chennai
final docsDir = await getApplicationDocumentsDirectory();
final Store store = await openStore(directory: "${docsDir.path}/nearby_places_example/");
final placeBox = store.box<Place>();
final query = placeBox.query(Place_.locationVector.nearestNeighborsF32(currentLocation, 3))
.build();
final nearbyCities = query.find();
store.close();
That’s it - you've now implemented offline vector search! 🎉
🧠 What Just Happened?
-
You stored float vectors
[latitude, longitude]
in ObjectBox -
The
nearestNeighbor()
feature compares them using cosine similarity - ObjectBox instantly returns the closest matches.
- While ObjectBox finds the nearest neighbors, we still need to calculate the actual distances to display to users.
All of this without writing a single line of distance math! 🙌
🔥 Real-World Use Cases
You can extend this to:
💬 Final Thoughts
With this simple demo, you’ve now added vector intelligence to your offline Flutter app — all using native Dart and ObjectBox’s magic.
Project source code github link - https://github.com/wh173d3v11/nearby_search_offline_flutter.git
This isn’t just about locations — the same concept works for ratings, tags, embeddings, or any type of multi-dimensional data.
Post a Comment