Skip to content

Commit 3f2e548

Browse files
committed
wip
1 parent 7cf0487 commit 3f2e548

File tree

2 files changed

+55
-29
lines changed

2 files changed

+55
-29
lines changed

Sources/StructuredQueriesCore/SQLite/FTS5.swift

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,41 @@ extension TableDefinition where QueryValue: FTS5 {
1111
/// - Parameter rankings: A dictionary mapping columns to accuracy of a match.
1212
/// - Returns: A BM25 ranking function.
1313
public func bm25(
14-
_ rankings: [PartialKeyPath<Self>: Double]
14+
_ rankings: [PartialKeyPath<Self>: Double] = [:]
1515
) -> some QueryExpression<Double> {
16-
guard !rankings.isEmpty else { return SQLQueryExpression("0") }
1716
var queryFragments: [QueryFragment] = ["\(QueryValue.self)"]
18-
var columnNameToRanking: QueryFragment = """
19-
CASE "name"
20-
"""
21-
for (keyPath, ranking) in rankings {
22-
guard let column = self[keyPath: keyPath] as? any WritableTableColumnExpression
23-
else {
24-
reportIssue(
25-
"""
26-
Key path cannot be used in 'bm25' function: \(keyPath)
17+
if !rankings.isEmpty {
18+
var columnNameToRanking: QueryFragment = """
19+
CASE "name"
20+
"""
21+
for (keyPath, ranking) in rankings {
22+
guard let column = self[keyPath: keyPath] as? any WritableTableColumnExpression
23+
else {
24+
reportIssue(
25+
"""
26+
Key path cannot be used in 'bm25' function: \(keyPath)
2727
28-
Must be a key path to a table column on '\(QueryValue.self)'.
28+
Must be a key path to a table column on '\(QueryValue.self)'.
29+
"""
30+
)
31+
continue
32+
}
33+
columnNameToRanking.append(
34+
"""
35+
WHEN \(bind: column.name) THEN \(ranking)
36+
"""
37+
)
38+
}
39+
columnNameToRanking.append(" ELSE 1 END")
40+
for offset in Self.writableColumns.indices {
41+
queryFragments.append(
42+
"""
43+
(SELECT \(columnNameToRanking) \
44+
FROM pragma_table_info(\(quote: QueryValue.tableName, delimiter: .text)) \
45+
WHERE "cid" = \(offset))
2946
"""
3047
)
31-
continue
3248
}
33-
columnNameToRanking.append(
34-
"""
35-
WHEN \(bind: column.name) THEN \(ranking)
36-
"""
37-
)
38-
}
39-
columnNameToRanking.append(" ELSE 1 END")
40-
for offset in Self.writableColumns.indices {
41-
queryFragments.append(
42-
"""
43-
(SELECT \(columnNameToRanking) \
44-
FROM pragma_table_info(\(quote: QueryValue.tableName, delimiter: .text)) \
45-
WHERE "cid" = \(offset))
46-
"""
47-
)
4849
}
4950
return SQLQueryExpression("bm25(\(queryFragments.joined(separator: ", ")))")
5051
}

Tests/StructuredQueriesTests/FTSTests.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,32 @@ extension SnapshotTests {
9797
SELECT "reminderTexts"."reminderID", "reminderTexts"."title", "reminderTexts"."notes", "reminderTexts"."listID", "reminderTexts"."listTitle", "reminderTexts"."tags"
9898
FROM "reminderTexts"
9999
WHERE ("reminderTexts" MATCH 'Week')
100-
ORDER BY bm25("reminderTexts", (SELECT CASE "name" WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 WHEN 'tags' THEN 2.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 0), (SELECT CASE "name" WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 WHEN 'tags' THEN 2.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 1), (SELECT CASE "name" WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 WHEN 'tags' THEN 2.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 2), (SELECT CASE "name" WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 WHEN 'tags' THEN 2.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 3), (SELECT CASE "name" WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 WHEN 'tags' THEN 2.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 4), (SELECT CASE "name" WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 WHEN 'tags' THEN 2.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 5))
100+
ORDER BY bm25("reminderTexts", (SELECT CASE "name" WHEN 'tags' THEN 2.0 WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 0), (SELECT CASE "name" WHEN 'tags' THEN 2.0 WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 1), (SELECT CASE "name" WHEN 'tags' THEN 2.0 WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 2), (SELECT CASE "name" WHEN 'tags' THEN 2.0 WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 3), (SELECT CASE "name" WHEN 'tags' THEN 2.0 WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 4), (SELECT CASE "name" WHEN 'tags' THEN 2.0 WHEN 'title' THEN 10.0 WHEN 'notes' THEN 5.0 ELSE 1 END FROM pragma_table_info('reminderTexts') WHERE "cid" = 5))
101+
"""
102+
} results: {
103+
"""
104+
┌────────────────────────────────┐
105+
│ ReminderText( │
106+
│ reminderID: 10, │
107+
│ title: "Send weekly emails", │
108+
│ notes: "", │
109+
│ listID: 3, │
110+
│ listTitle: "Business", │
111+
│ tags: ""
112+
│ ) │
113+
└────────────────────────────────┘
114+
"""
115+
}
116+
assertQuery(
117+
ReminderText
118+
.where { $0.match("Week") }
119+
.order { $0.bm25() }
120+
) {
121+
"""
122+
SELECT "reminderTexts"."reminderID", "reminderTexts"."title", "reminderTexts"."notes", "reminderTexts"."listID", "reminderTexts"."listTitle", "reminderTexts"."tags"
123+
FROM "reminderTexts"
124+
WHERE ("reminderTexts" MATCH 'Week')
125+
ORDER BY bm25("reminderTexts")
101126
"""
102127
} results: {
103128
"""

0 commit comments

Comments
 (0)