From 97e6e00be322f871786ec782a83b873f52eeeafe Mon Sep 17 00:00:00 2001 From: Hayden Date: Thu, 22 Aug 2024 21:29:13 +0700 Subject: [PATCH] feat: allow multi-search and single collection search to return raw data --- Sources/Typesense/Documents.swift | 5 ++ Sources/Typesense/MultiSearch.swift | 7 +++ Tests/TypesenseTests/DocumentTests.swift | 22 +++++++ Tests/TypesenseTests/MultiSearchTests.swift | 64 +++++++++++++++++++++ 4 files changed, 98 insertions(+) diff --git a/Sources/Typesense/Documents.swift b/Sources/Typesense/Documents.swift index c225e05..3741738 100644 --- a/Sources/Typesense/Documents.swift +++ b/Sources/Typesense/Documents.swift @@ -75,6 +75,11 @@ public struct Documents { } + public func search(_ searchParameters: SearchParameters) async throws -> (Data?, URLResponse?) { + let queryParams = try createURLQuery(forSchema: searchParameters) + return try await apiCall.get(endPoint: "\(RESOURCEPATH)/search", queryParameters: queryParams) + } + public func search(_ searchParameters: SearchParameters, for: T.Type) async throws -> (SearchResult?, URLResponse?) { var searchQueryParams: [URLQueryItem] = [] diff --git a/Sources/Typesense/MultiSearch.swift b/Sources/Typesense/MultiSearch.swift index 30883d1..a502fec 100644 --- a/Sources/Typesense/MultiSearch.swift +++ b/Sources/Typesense/MultiSearch.swift @@ -11,6 +11,13 @@ public struct MultiSearch { self.apiCall = apiCall } + public func perform(searchRequests: [MultiSearchCollectionParameters], commonParameters: MultiSearchParameters) async throws -> (Data?, URLResponse?) { + let queryParams = try createURLQuery(forSchema: commonParameters) + let searchesData = try encoder.encode(MultiSearchSearchesParameter(searches: searchRequests)) + + return try await apiCall.post(endPoint: "\(RESOURCEPATH)", body: searchesData, queryParameters: queryParams) + } + public func perform(searchRequests: [MultiSearchCollectionParameters], commonParameters: MultiSearchParameters, for: T.Type) async throws -> (MultiSearchResult?, URLResponse?) { var searchQueryParams: [URLQueryItem] = [] diff --git a/Tests/TypesenseTests/DocumentTests.swift b/Tests/TypesenseTests/DocumentTests.swift index af8242d..e2fd16f 100644 --- a/Tests/TypesenseTests/DocumentTests.swift +++ b/Tests/TypesenseTests/DocumentTests.swift @@ -196,6 +196,28 @@ final class DocumentTests: XCTestCase { } + func testDocumentSearchReturnRawData() async { + let searchParams = SearchParameters(q: "stark", queryBy: "company_name", filterBy: "num_employees:>100", sortBy: "num_employees:desc") + + do { + try await createDocument() + let (data, _) = try await client.collection(name: "companies").documents().search(searchParams) + guard let validData = data else { + throw DataError.dataNotFound + } + if let json = try JSONSerialization.jsonObject(with: validData, options: []) as? [String: Any]{ + XCTAssertNotNil(json["hits"]) + XCTAssertNotNil(json["found"]) + } else{ + XCTAssertTrue(false) + } + } catch (let error) { + print(error.localizedDescription) + XCTAssertTrue(false) + } + + } + func testDocumentSearchWithPreset() async { let productSchema = CollectionSchema(name: "products", fields: [ Field(name: "name", type: "string"), diff --git a/Tests/TypesenseTests/MultiSearchTests.swift b/Tests/TypesenseTests/MultiSearchTests.swift index b19fb4c..131e21b 100644 --- a/Tests/TypesenseTests/MultiSearchTests.swift +++ b/Tests/TypesenseTests/MultiSearchTests.swift @@ -78,6 +78,70 @@ final class MultiSearchTests: XCTestCase { } + func testMultiSearchReturnRawData() async { + let productSchema = CollectionSchema(name: "products", fields: [ + Field(name: "name", type: "string"), + Field(name: "price", type: "int32"), + Field(name: "brand", type: "string"), + Field(name: "desc", type: "string"), + ]) + + let brandSchema = CollectionSchema(name: "brands", fields: [ + Field(name: "name", type: "string"), + ]) + + let searchRequests = [ + MultiSearchCollectionParameters(q: "shoe", filterBy: "price:=[50..120]", collection: "products"), + MultiSearchCollectionParameters(q: "Nike", collection: "brands"), + ] + + let brand1 = Brand(name: "Nike") + let product1 = Product(name: "Jordan", price: 70, brand: "Nike", desc: "High quality shoe") + + let commonParams = MultiSearchParameters(queryBy: "name") + + do { + do { + let _ = try await client.collections.create(schema: productSchema) + } catch (let error) { + print(error.localizedDescription) + XCTAssertTrue(false) + } + + do { + let _ = try await client.collections.create(schema: brandSchema) + } catch (let error) { + print(error.localizedDescription) + XCTAssertTrue(false) + } + + let (_,_) = try await client.collection(name: "products").documents().create(document: encoder.encode(product1)) + + let (_,_) = try await client.collection(name: "brands").documents().create(document: encoder.encode(brand1)) + + let (data, _) = try await client.multiSearch().perform(searchRequests: searchRequests, commonParameters: commonParams) + + guard let validData = data else { + throw DataError.dataNotFound + } + if let json = try JSONSerialization.jsonObject(with: validData, options: []) as? [String: Array<[String: Any]>]{ + print(json) + XCTAssertNotNil(json["results"]?[0]) + XCTAssertNotNil(json["results"]?[1]) + } else{ + XCTAssertTrue(false) + } + } catch HTTPError.serverError(let code, let desc) { + print(desc) + print("The response status code is \(code)") + XCTAssertTrue(false) + } catch (let error) { + print(error.localizedDescription) + XCTAssertTrue(false) + } + + } + func testMultiSearchWithPreset() async { let productSchema = CollectionSchema(name: "products", fields: [ Field(name: "name", type: "string"),