Header Ads Widget

Responsive Advertisement

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:

  1. Connectivity requirements: Users in areas with poor connectivity can't access location data
  2. API costs: Location service APIs often charge per request
  3. 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

Link copied to clipboard!