---
title: "Geo radius search in C#"
url: https://recursiveai.org/oneindex/cookbook/geo-radius-search-csharp/
description: "Find indexed points within a radius and return them nearest first. This example uses OneIndex 0.4.0-preview.2, a preview release."
version: "0.4.0-preview.2"
---

# Geo radius search in C#

**OneIndex** is a free, open-source search library for .NET from Recursive AI. MIT or Apache-2.0, preview, runs in-process.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneIndex) · [GitHub](https://github.com/recursive-ai-oss/oneindex-csharp) · [Docs](https://recursiveai.org/oneindex/docs/) · [Download example (.zip)](https://recursiveai.org/oneindex/cookbook/geo-radius-search-csharp/geo-radius-search-csharp.zip)

To search by location in C#, filter a `[Geo]` field by radius and sort by distance. Coordinates are latitude and longitude in degrees; the radius is in meters. This uses the preview release `0.4.0-preview.2`.

```shell
dotnet add package RecursiveAI.OneIndex
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using OneIndex;

using var index = SearchIndex.InMemory<Place>();
index.Upsert([
    new() { Id = "center", Location = new(45.4727, 9.1840) },
    new() { Id = "near", Location = new(45.4800, 9.1840) },
    new() { Id = "far", Location = new(46.0000, 9.1840) }
]);
index.Commit();
var hits = index.Search()
    .Where(p => Geo.WithinRadius(
        p.Location, 45.4727, 9.1840, 2000))
    .OrderByDistance(p => p.Location, 45.4727, 9.1840)
    .Execute();
foreach (var hit in hits)
    Console.WriteLine(hit.Document.Id);

public class Place
{
    [SearchId] public string Id { get; set; } = "";
    [Geo] public GeoPoint Location { get; set; }
}
```

```text
center
near
```

The three invented coordinates are included in the code: the query center, a point nearby and a point farther north. The in-memory index starts empty on every run.

Invalid coordinates or a nonfinite or negative radius are rejected; see the [geo input rules](https://recursiveai.org/oneindex/docs/geo/).

Unzip [the example](https://recursiveai.org/oneindex/cookbook/geo-radius-search-csharp/geo-radius-search-csharp.zip), then `dotnet run`.

## Variations

**Reduce the radius to 500 meters.** Replace the search and print loop in the full program with this snippet.

```csharp
var nearby = index.Search()
    .Where(p => Geo.WithinRadius(
        p.Location, 45.4727, 9.1840, 500))
    .OrderByDistance(p => p.Location, 45.4727, 9.1840)
    .Execute();
foreach (var hit in nearby)
    Console.WriteLine(hit.Document.Id);
```

```text
center
```

## Related recipes

- [Full-text search in C#](https://recursiveai.org/oneindex/cookbook/full-text-search-csharp/)
- [Rebuild a search index in C#](https://recursiveai.org/oneindex/cookbook/rebuild-search-index/)

## The short answer

To search by location in C#, store coordinates in a OneIndex `[Geo]` field, filter with `Geo.WithinRadius`, and sort with `OrderByDistance`. Latitude and longitude are in degrees; the radius is in meters. This example returns the two invented points inside a radius of 2,000 meters, nearest first.

The sample uses the pinned `0.4.0-preview.2` package, a preview release. It creates an in-memory index, inserts three documents and commits them before searching. The [geo search documentation](https://recursiveai.org/oneindex/docs/geo/) defines filtering, sorting and coordinate validation for this version.

## How do I write a geo search query?

Represent a searchable place with a document ID and a `GeoPoint` property marked `[Geo]`. Use latitude first and longitude second when constructing a point and when supplying the query center. Reversing the numbers can produce a valid coordinate in a completely different place, so constructor validation alone cannot catch that application error.

A radius filter decides which documents match; it does not by itself request nearest-first ordering. The sample adds `OrderByDistance` with the same field and center to make that order explicit. The outer point at latitude 46 is excluded, while the center point is returned before the nearby point. The variation reduces the radius and returns only the center.

Filtering and sorting are separate decisions. Use the radius to express the geographic region your application accepts, then choose whether proximity is the desired order. The LINQ geo predicate can be combined with other predicates using the documented boolean operators.

## How does geo location search work?

OneIndex uses a haversine great-circle distance on a sphere, not driving distance or walking time. The documented sphere radius is 6,371,008.8 meters. That definition is useful for understanding borderline matches: a straight geographic radius does not describe road accessibility or a route around barriers.

The index proposes candidate points and then confirms them using their stored exact coordinates. Radius matching therefore does not depend on the geo index’s coordinate quantization. A segment with no values for that geo field matches nothing. Documents may hold several points per geo field, as described in the geo documentation; the sample deliberately keeps one per document.

A bounding-box query answers a different question: membership in latitude and longitude bounds, not distance from a center. Choose that shape when the requirement is a rectangular map viewport. Choose a radius when the requirement is distance from a point. Neither automatically assigns names to addresses; the example already has numeric coordinates before indexing.

Latitude must be within -90 through 90 and longitude within -180 through 180. `GeoPoint` rejects invalid coordinates and NaN. A radius must be finite and nonnegative; invalid inputs are rejected at construction or parsing rather than silently corrected. A radius larger than half the circumference matches every point.

The downloadable program uses `InMemory` so each run starts with the same three documents. For persistent application data, the same geo field and query concepts apply to an opened index, but the application must manage its own index path, updates and commit lifecycle.
