使用 Typesense 在 iOS 上实现搜索的绝佳新方式 ⚡️🔍✨ Typesense Swift 是一个高阶封装器,可帮助你轻松地使用 Typesense 实现搜索。
将 Typesense Swift
Swift 包添加到你的项目中。你可以参考 Apple 的文档 将 Typesense Swift 作为依赖项添加到你的 iOS 项目中。你也可以通过将以下行添加到 Package.swift
的 dependencies 数组中,将 Typesense 导入到你自己的 Swift 包中
...
dependencies: [
.package(url: "https://github.com/typesense/typesense-swift", .upToNextMajor(from: "1.0.0"),
],
...
将 Typesense 导入到你的 Swift 项目中
import Typesense
声明可用的 Typesense 节点作为 Node
成员
let node1 = Node(url: "https://:8108") // or
let node2 = Node(host: "xxx-1.a1.typesense.net", port: "443", nodeProtocol: "https")
使用提到的节点创建配置,并由此创建客户端
let myConfig = Configuration(nodes: [node1, node2], apiKey: "coolstuff")
let client = Client(config: myConfig)
在创建配置时,你可以使用 Typesense 参数,如 nearestNode
和 connectionTimeoutSeconds
。你也可以传入 logger
参数来调试代码,如下所示
let myConfig = Configuration(nodes: [node1, node2], apiKey: "coolstuff", logger: Logger(debugMode: true))
你可以通过首先定义集合模式来创建一个集合
let myCoolSchema = CollectionSchema(name: "schools", fields: [Field(name: "school_name", type: "string"), Field(name: "num_students", type: "int32"), Field(name: "country", type: "string", facet: true)], defaultSortingField: "num_students")
let (data, response) = try await client.collections.create(schema: myCoolSchema)
根据你的集合定义你的文档结构,并通过将其插入/更新到集合中来索引它
struct School: Codable {
var id: String
var school_name: String
var num_students: Int
var country: String
}
let document = School(id: "7", school_name: "Hogwarts", num_students: 600, country: "United Kingdom")
let documentData = try JSONEncoder().encode(document)
let (data, response) = try await client.collection(name: "schools").documents().create(document: documentData)
//or
let (data, response) = try await client.collection(name: "schools").documents().upsert(document: documentData)
你可以对属于特定集合的 Collections
和 Documents
执行 CRUD 操作。你也可以在 documents()
方法上使用 .importBatch()
来导入和索引一批文档(以 .jsonl 格式)。
清楚地定义你的 搜索参数,然后通过提及你的文档类型来执行搜索操作
let searchParameters = SearchParameters(q: "hog", queryBy: "school_name", filterBy: "num_students:>500", sortBy: "num_students:desc")
let (data, response) = try await client.collection(name: "schools").documents().search(searchParameters, for: School.self)
这将返回一个 SearchResult
对象作为数据,可以根据需要进一步解析。
let jsonL = Data("{}".utf8)
let (data, response) = try await client.collection(name: "companies").documents().importBatch(jsonL, options: ImportDocumentsParameters(
action: .upsert,
batchSize: 10,
dirtyValues: .drop,
remoteEmbeddingBatchSize: 10,
returnDoc: true,
returnId: false
))
let (data, response) = try await client.collection(name: "companies").documents().update(
document: ["company_size": "large"],
options: UpdateDocumentsByFilterParameters(filterBy: "num_employees:>1000")
)
let (data, response) = try await client.collection(name: "companies").documents().delete(
options: DeleteDocumentsParameters(filterBy: "num_employees:>100")
)
let (data, response) = try await client.collection(name: "companies").documents().export(options: ExportDocumentsParameters(excludeFields: "country"))
let schema = CollectionAliasSchema(collectionName: "companies_june")
let (data, response) = try await client.aliases().upsert(name: "companies", collection: schema)
let (data, response) = try await client.aliases().retrieve()
let (data, response) = try await client.aliases().retrieve(name: "companies")
let (data, response) = try await client.aliases().delete(name: "companies")
let adminKey = ApiKeySchema(_description: "Test key with all privileges", actions: ["*"], collections: ["*"])
let (data, response) = try await client.keys().create(adminKey)
let (data, response) = try await client.keys().retrieve()
let (data, response) = try await client.keys().retrieve(id: 1)
let (data, response) = try await client.keys().delete(id: 1)
let schema = ConversationModelCreateSchema(
_id: "conv-model-1",
modelName: "openai/gpt-3.5-turbo",
apiKey: "OPENAI_API_KEY",
historyCollection: "conversation_store",
systemPrompt: "You are an assistant for question-answering...",
ttl: 10000,
maxBytes: 16384
)
let (data, response) = try await client.conversations().models().create(params: schema)
let (data, response) = try await client.conversations().models().retrieve()
let (data, response) = try await client.conversations().model(modelId: "conv-model-1").retrieve()
let (data, response) = try await client.conversations().model(modelId: "conv-model-1").update(params: ConversationModelUpdateSchema(
systemPrompt: "..."
))
let (data, response) = try await client.conversations().model(modelId: "conv-model-1").delete()
let schema = SearchOverrideSchema<MetadataType>(
rule: SearchOverrideRule(tags: ["test"], query: "apple", match: SearchOverrideRule.Match.exact, filterBy: "employees:=50"),
includes: [SearchOverrideInclude(_id: "include-id", position: 1)],
excludes: [SearchOverrideExclude(_id: "exclude-id")],
filterBy: "test:=true",
removeMatchedTokens: false,
metadata: MetadataType(message: "test-json"),
sortBy: "num_employees:desc",
replaceQuery: "test",
filterCuratedHits: false,
effectiveFromTs: 123,
effectiveToTs: 456,
stopProcessing: false
)
let (data, response) = try await client.collection(name: "books").overrides().upsert(overrideId: "test-id", params: schema)
let (data, response) = try await client.collection(name: "books").overrides().retrieve(metadataType: Never.self)
let (data, response) = try await client.collection(name: "books").override("test-id").retrieve(metadataType: MetadataType.self)
let (data, response) = try await client.collection(name: "books").override("test-id").delete()
let schema = PresetUpsertSchema(
value: PresetValue.singleCollectionSearch(SearchParameters(q: "apple"))
// or: value: PresetValue.multiSearch(MultiSearchSearchesParameter(searches: [MultiSearchCollectionParameters(q: "apple")]))
)
let (data, response) = try await client.presets().upsert(presetName: "listing_view", params: schema)
let (data, response) = try await client.presets().retrieve()
let (data, response) = try await client.preset("listing_view").retrieve()
switch data?.value {
case .singleCollectionSearch(let value):
print(value)
case .multiSearch(let value):
print(value)
}
let (data, response) = try await client.preset("listing_view").delete()
let schema = StopwordsSetUpsertSchema(
stopwords: ["states","united"],
locale: "en"
)
let (data, response) = try await client.stopwords().upsert(stopwordsSetId: "stopword_set1", params: schema)
let (data, response) = try await client.stopwords().retrieve()
let (data, response) = try await client.stopword("stopword_set1").retrieve()
let (data, response) = try await client.stopword("stopword_set1").delete()
let schema = SearchSynonymSchema(synonyms: ["blazer", "coat", "jacket"])
let (data, response) = try await client.collection(name: "products").synonyms().upsert(id: "coat-synonyms", schema)
let (data, response) = try await client.collection(name: "products").synonyms().retrieve()
let (data, response) = try await client.collection(name: "products").synonyms().retrieve(id: "coat-synonyms")
let (data, response) = try await myClient.collection(name: "products").synonyms().delete(id: "coat-synonyms")
let (data, response) = try await client.operations().getDebug()
let (data, response) = try await client.operations().getHealth()
let (data, response) = try await client.operations().getStats()
let (data, response) = try await client.operations().getMetrics()
let (data, response) = try await client.operations().vote()
let (data, response) = try await client.operations().toggleSlowRequestLog(seconds: 2)
let (data, response) = try await client.operations().clearCache()
let (data, response) = try await client.operations().snapshot(path: "/tmp/typesense-data-snapshot")
欢迎在 GitHub 上提交 Issues 和 Pull Requests 到 Typesense Swift。请注意,Swift 客户端中使用的模型是由 Swagger-Codegen 生成的,并且被自动化修改以防止重大错误。因此,请务必使用仓库中提供的 shell 脚本来生成模型
sh get-models.sh
生成的模型(在 Models 目录中)也需要在源代码的 Models 目录中使用。当 Typesense-Api-Spec 更新时,需要生成模型。