Skip to content

Commit 610bb10

Browse files
committed
fix: address review feedback
1 parent 140938e commit 610bb10

6 files changed

Lines changed: 19 additions & 52 deletions

File tree

NUGET-README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ParadeDB for Entity Framework Core
22

3-
The official [Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/) integration for [ParadeDB](https://paradedb.com), including first-class support for managing BM25 indexes and running queries using the full ParadeDB API. Follow the [getting started guide](https://docs.paradedb.com/documentation/getting-started/environment#entity-framework-core) to begin.
3+
The official [Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/) integration for [ParadeDB](https://paradedb.com), including first-class support for managing BM25 indexes and running queries using the full ParadeDB API. The integration covers both full-text and vector search — vector search indexes pgvector `vector` columns directly, with no separate pgvector ORM plugin required. Follow the [getting started guide](https://docs.paradedb.com/documentation/getting-started/environment#entity-framework-core) to begin.
44

55
## Requirements & Compatibility
66

@@ -10,6 +10,7 @@ The official [Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/)
1010
| EF Core | 8.0+ |
1111
| ParadeDB | 0.25.0+ |
1212
| PostgreSQL | 15+ (with ParadeDB extension) |
13+
| pgvector | Required for vector search |
1314

1415
## Examples
1516

README.md

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
## ParadeDB for Entity Framework Core
3838

39-
The official [Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/) integration for [ParadeDB](https://paradedb.com) (powered by the [`pg_search`](https://github.com/paradedb/paradedb) Postgres extension), including first-class support for managing BM25 indexes and running queries using the full ParadeDB API. Follow the [getting started guide](https://docs.paradedb.com/documentation/getting-started/environment#entity-framework-core) to begin.
39+
The official [Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/) integration for [ParadeDB](https://paradedb.com) (powered by the [`pg_search`](https://github.com/paradedb/paradedb) Postgres extension), including first-class support for managing BM25 indexes and running queries using the full ParadeDB API. The integration covers both full-text and vector search — vector search indexes pgvector `vector` columns directly, with no separate pgvector ORM plugin required. Follow the [getting started guide](https://docs.paradedb.com/documentation/getting-started/environment#entity-framework-core) to begin.
4040

4141
## Requirements & Compatibility
4242

@@ -46,49 +46,7 @@ The official [Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/)
4646
| EF Core | 8.0+ |
4747
| ParadeDB | 0.25.0+ |
4848
| PostgreSQL | 15+ (with ParadeDB extension) |
49-
50-
## Vector Search
51-
52-
ParadeDB indexes pgvector `vector` columns directly inside its BM25 index — no
53-
pgvector ORM plugin is required. Map a `float[]` property to a `vector(n)`
54-
column, pick a distance metric for the index, and order by the matching
55-
distance function:
56-
57-
```csharp
58-
public class Item
59-
{
60-
public int Id { get; set; }
61-
public float[]? Embedding { get; set; }
62-
}
63-
64-
// Model configuration
65-
modelBuilder.Entity<Item>(entity =>
66-
{
67-
entity.Property(x => x.Embedding).HasVectorType(384);
68-
69-
entity
70-
.HasParadeDbIndex("items_idx", x => x.Id)
71-
.HasField(x => x.Embedding, VectorMetric.Cosine);
72-
});
73-
74-
// Top-K query: a `@@@` predicate (`EF.Functions.All` for match-all here) and
75-
// a LIMIT (`Take`) are required for the index to serve the query
76-
float[] queryEmbedding = GetQueryEmbedding();
77-
78-
var results = await db
79-
.Items.Where(x => EF.Functions.All(x.Id))
80-
.OrderBy(x => EF.Functions.CosineDistance(x.Embedding, queryEmbedding))
81-
.Take(10)
82-
.ToListAsync();
83-
```
84-
85-
`VectorMetric.L2` (`<->`, the default), `VectorMetric.Cosine` (`<=>`), and
86-
`VectorMetric.InnerProduct` (`<#>`) map to the `vector_l2_ops`,
87-
`vector_cosine_ops`, and `vector_ip_ops` operator classes. The distance
88-
function used in `OrderBy` must match the metric of the index opclass —
89-
`L2Distance` with `L2`, `CosineDistance` with `Cosine`, and `InnerProduct`
90-
with `InnerProduct` — otherwise the query still returns correct results but
91-
falls back to a sequential scan instead of Top-K index pushdown.
49+
| pgvector | Required for vector search |
9250

9351
## Examples
9452

examples/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ dotnet run --project examples/Examples.csproj -p:Example=HybridRrf
4949

5050
## Vector Search (`examples/VectorSearch`)
5151

52-
Runs Top-K nearest-neighbor queries over a pgvector column with the native
53-
vector support, backed by a bm25 index when the server supports it.
52+
Runs Top-K nearest-neighbor queries over a pgvector column with ParadeDB
53+
vector support, backed by a paradedb index.
5454

5555
```bash
5656
dotnet run --project examples/Examples.csproj -p:Example=VectorSearch

examples/Shared/ExampleSetup.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ await db.Database.ExecuteSqlRawAsync(
4646
"CALL paradedb.create_bm25_test_table(schema_name => 'public', table_name => 'mock_items')"
4747
);
4848
await db.Database.ExecuteSqlRawAsync("DROP INDEX IF EXISTS mock_items_bm25_idx");
49+
// The VectorSearch example may have left its own index behind, and newer
50+
// pg_search versions allow only one ParadeDB index per table
51+
await db.Database.ExecuteSqlRawAsync("DROP INDEX IF EXISTS mock_items_vector_idx");
4952
await db.Database.ExecuteSqlRawAsync(
5053
"""
5154
CREATE INDEX mock_items_bm25_idx ON mock_items
@@ -102,14 +105,18 @@ public static async Task SetupHybridAsync(DbContext db)
102105
{
103106
await SetupMockItemsAsync(db);
104107
await db.Database.ExecuteSqlRawAsync("CREATE EXTENSION IF NOT EXISTS vector");
108+
// Newer pg_search versions create mock_items with an embedding column of a
109+
// different dimension; the examples use 384-dimensional embeddings
105110
await db.Database.ExecuteSqlRawAsync(
106111
"""
107112
DO $$
108113
BEGIN
109-
IF NOT EXISTS (
110-
SELECT 1 FROM information_schema.columns
111-
WHERE table_name = 'mock_items' AND column_name = 'embedding'
112-
) THEN
114+
IF (
115+
SELECT atttypmod FROM pg_attribute
116+
WHERE attrelid = 'mock_items'::regclass
117+
AND attname = 'embedding' AND NOT attisdropped
118+
) IS DISTINCT FROM 384 THEN
119+
ALTER TABLE mock_items DROP COLUMN IF EXISTS embedding;
113120
ALTER TABLE mock_items ADD COLUMN embedding vector(384);
114121
END IF;
115122
END $$;

examples/VectorSearch/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
await ExampleSetup.SetupHybridAsync(dbContext);
2020
await EmbeddingLoader.LoadAsync(dbContext);
2121

22+
// Newer pg_search versions allow only one ParadeDB index per table
23+
await dbContext.Database.ExecuteSqlRawAsync("DROP INDEX IF EXISTS mock_items_bm25_idx");
2224
await dbContext.Database.ExecuteSqlRawAsync("DROP INDEX IF EXISTS mock_items_vector_idx");
2325
await dbContext.Database.ExecuteSqlRawAsync(
2426
"""

src/Internal/ParadeDbOptionsExtension.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
1414
#endif
1515

16-
1716
namespace ParadeDB.EntityFrameworkCore.Internal;
1817

1918
internal sealed class ParadeDbOptionsExtension : IDbContextOptionsExtension

0 commit comments

Comments
 (0)