Skip to content

Commit

Permalink
Merge #417
Browse files Browse the repository at this point in the history
417: [1.4.0] Refactor Settings and Add Pagination, Separator and Dictionary Settings r=curquiza a=Sherlouk

# Pull Request

## Related issue
Fixes #308
Fixes changes raised under meilisearch/integration-guides#286 (#406) - ⚠️ Wait for v1.4.0

## What does this PR do?
- Refactors index settings to improve reuse (functionally identical, but around 300 less lines of code)
- Cleaning up some unsafe practices in unit tests
- Adds support for three new types of index-level settings (improving parity)

All integration tests have been run against v1.4.0 (pre-release) RC 2 and is running locally. CI uses the latest version of the executable (1.3.0) and thus will not work and will throw errors. This is expected. This PR won't be merged until after the 1.4.0 release due to Swift being a tier 3 project, as such we can simply re-run CI once that's released.

This PR starts to contain a little bit of cleanup with some various nit picks (nothing that changes the code style though).

## PR checklist
Please check if your PR fulfills the following requirements:
- [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
- [x] Have you read the contributing guidelines?
- [x] Have you made sure that the title is accurate and descriptive of the changes?

Thank you so much for contributing to Meilisearch!


Co-authored-by: James Sherlock <[email protected]>
  • Loading branch information
meili-bors[bot] and Sherlouk authored Sep 27, 2023
2 parents 4c6d2f4 + d15cc4b commit 4913acb
Show file tree
Hide file tree
Showing 12 changed files with 944 additions and 535 deletions.
46 changes: 41 additions & 5 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,44 @@ async_guide_canceled_by: |-
print(error)
}
}
get_dictionary_1: |-
client.index("books").getDictionary { result in
// handle result
}
update_dictionary_1: |-
client.index("books").updateDictionary(["J. R. R.", "W. E. B."]) { result in
// handle result
}
reset_dictionary_1: |-
client.index("books").resetDictionary { result in
// handle result
}
get_separator_tokens_1: |-
client.index("books").getSeparatorTokens { result in
// handle result
}
update_separator_tokens_1: |-
client.index("books").updateSeparatorTokens(["|", "&hellip;"]) { result in
// handle result
}
reset_separator_tokens_1: |-
client.index("books").resetSeparatorTokens { result in
// handle result
}
get_non_separator_tokens_1: |-
client.index("books").getNonSeparatorTokens { result in
// handle result
}
update_non_separator_tokens_1: |-
client.index("books").updateNonSeparatorTokens(["@", "#"]) { result in
// handle result
}
reset_non_separator_tokens_1: |-
client.index("books").resetNonSeparatorTokens { result in
// handle result
}
search_parameter_guide_hitsperpage_1: |-
let searchParameters = SearchParameters.query("", hitsPerPage: 15)
let searchParameters = SearchParameters(query: "", hitsPerPage: 15)
client.index("movies").search(searchParameters) { (result: Result<Searchable<Movie>, Swift.Error>) in
switch result {
case .success(let searchResult):
Expand All @@ -179,7 +215,7 @@ search_parameter_guide_hitsperpage_1: |-
}
}
search_parameter_guide_page_1: |-
let searchParameters = SearchParameters.query("", page: 15)
let searchParameters = SearchParameters(query: "", page: 15)
client.index("movies").search(searchParameters) { (result: Result<Searchable<Movie>, Swift.Error>) in
switch result {
case .success(let searchResult):
Expand Down Expand Up @@ -362,7 +398,7 @@ delete_documents_1: |-
}
}
search_post_1: |-
let searchParameters = SearchParameters.query("American ninja")
let searchParameters = SearchParameters(query: "American ninja")
client.index("movies").search(searchParameters) { (result: Result<Searchable<Movie>, Swift.Error>) in
switch result {
case .success(let searchResult):
Expand Down Expand Up @@ -458,7 +494,7 @@ delete_a_key_1: |-
security_guide_search_key_1: |-
client = try MeiliSearch(host: "http://localhost:7700", apiKey: "apiKey")
client.index("patient_medical_records")
.search(SearchParameters.query("")) { (result: Result<Searchable<Patient>, Swift.Error>) in
.search(SearchParameters(query: "")) { (result: Result<Searchable<Patient>, Swift.Error>) in
switch result {
case .success(let searchResult):
print(searchResult)
Expand Down Expand Up @@ -1454,7 +1490,7 @@ geosearch_guide_filter_usage_2: |-
}
geosearch_guide_filter_usage_3: |-
let searchParameters = SearchParameters(
filter: '_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])'
filter: "_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])"
)
client.index("restaurants").search(searchParameters) { (result: Result<Searchable<Restaurant>, Swift.Error>) in
switch result {
Expand Down
161 changes: 161 additions & 0 deletions Sources/MeiliSearch/Indexes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,167 @@ public struct Indexes {
_ completion: @escaping (Result<TaskInfo, Swift.Error>) -> Void) {
self.settings.resetSortableAttributes(self.uid, completion)
}

// MARK: Separator Tokens

/**
Fetch the `separatorTokens` setting of a Meilisearch index.

- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains an `[String]`
value if the request was successful, or `Error` if a failure occurred.
*/
public func getSeparatorTokens(
_ completion: @escaping (Result<[String], Swift.Error>) -> Void) {
self.settings.getSeparatorTokens(self.uid, completion)
}

/**
Modify the `separatorTokens` setting of a Meilisearch index.

- parameter attributes: List of tokens that will be considered as word separators
- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains `TaskInfo`
value if the request was successful, or `Error` if a failure occurred.
*/
public func updateSeparatorTokens(
_ attributes: [String],
_ completion: @escaping (Result<TaskInfo, Swift.Error>) -> Void) {
self.settings.updateSeparatorTokens(self.uid, attributes, completion)
}

/**
Reset the `separatorTokens` setting of a Meilisearch index to the default value `[]`.

- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains `TaskInfo`
value if the request was successful, or `Error` if a failure occurred.
*/
public func resetSeparatorTokens(
_ completion: @escaping (Result<TaskInfo, Swift.Error>) -> Void) {
self.settings.resetSeparatorTokens(self.uid, completion)
}

// MARK: Non Separator Tokens

/**
Fetch the `nonSeparatorTokens` setting of a Meilisearch index.

- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains an `[String]`
value if the request was successful, or `Error` if a failure occurred.
*/
public func getNonSeparatorTokens(
_ completion: @escaping (Result<[String], Swift.Error>) -> Void) {
self.settings.getNonSeparatorTokens(self.uid, completion)
}

/**
Modify the `nonSeparatorTokens` setting of a Meilisearch index.

- parameter attributes: List of tokens that will not be considered as word separators
- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains `TaskInfo`
value if the request was successful, or `Error` if a failure occurred.
*/
public func updateNonSeparatorTokens(
_ attributes: [String],
_ completion: @escaping (Result<TaskInfo, Swift.Error>) -> Void) {
self.settings.updateNonSeparatorTokens(self.uid, attributes, completion)
}

/**
Reset the `nonSeparatorTokens` setting of a Meilisearch index to the default value `[]`.

- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains `TaskInfo`
value if the request was successful, or `Error` if a failure occurred.
*/
public func resetNonSeparatorTokens(
_ completion: @escaping (Result<TaskInfo, Swift.Error>) -> Void) {
self.settings.resetNonSeparatorTokens(self.uid, completion)
}

// MARK: Dictionary

/**
Fetch the `dictionary` setting of a Meilisearch index.

- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains an `[String]`
value if the request was successful, or `Error` if a failure occurred.
*/
public func getDictionary(
_ completion: @escaping (Result<[String], Swift.Error>) -> Void) {
self.settings.getDictionary(self.uid, completion)
}

/**
Modify the `dictionary` setting of a Meilisearch index.

- parameter attributes: List of words on which the segmentation will be overridden
- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains `TaskInfo`
value if the request was successful, or `Error` if a failure occurred.
*/
public func updateDictionary(
_ attributes: [String],
_ completion: @escaping (Result<TaskInfo, Swift.Error>) -> Void) {
self.settings.updateDictionary(self.uid, attributes, completion)
}

/**
Reset the `dictionary` setting of a Meilisearch index to the default value `[]`.

- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains `TaskInfo`
value if the request was successful, or `Error` if a failure occurred.
*/
public func resetDictionary(
_ completion: @escaping (Result<TaskInfo, Swift.Error>) -> Void) {
self.settings.resetDictionary(self.uid, completion)
}

// MARK: Pagination

/**
Get the pagination settings for the current index.

- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains an `Pagination`
value if the request was successful, or `Error` if a failure occurred.
*/
public func getPaginationSettings(
_ completion: @escaping (Result<Pagination, Swift.Error>) -> Void) {
self.settings.getPaginationSettings(self.uid, completion)
}

/**
Updates the pagination setting for the index.

- parameter settings: The new preferences to use for pagination.
- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains `TaskInfo`
value if the request was successful, or `Error` if a failure occurred.
*/
public func updatePaginationSettings(
_ settings: Pagination,
_ completion: @escaping (Result<TaskInfo, Swift.Error>) -> Void) {
self.settings.updatePaginationSettings(self.uid, settings, completion)
}

/**
Reset the pagination settings for the index.

- parameter completion: The completion closure is used to notify when the server
completes the query request, it returns a `Result` object that contains `TaskInfo`
value if the request was successful, or `Error` if a failure occurred.
*/
public func resetPaginationSettings(
_ completion: @escaping (Result<TaskInfo, Swift.Error>) -> Void) {
self.settings.resetPaginationSettings(self.uid, completion)
}

// MARK: Stats

/**
Expand Down
2 changes: 1 addition & 1 deletion Sources/MeiliSearch/Model/FacetStats.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public struct FacetStats: Codable, Equatable {

/// The minimum value found in the given facet
public let min: Double

/// The maximum value found in the given facet
public let max: Double
}
14 changes: 14 additions & 0 deletions Sources/MeiliSearch/Model/Pagination.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation

/**
`Pagination` is a wrapper used in the index pagination setting routes to handle the returned data.
*/
public struct Pagination: Codable, Equatable {
/// The maximum number of hits (document records) which can be returned by a single search request.
/// By default, Meilisearch returns 1000 results per search. This limit protects your database from malicious scraping.
public let maxTotalHits: Int

public init(maxTotalHits: Int) {
self.maxTotalHits = maxTotalHits
}
}
2 changes: 1 addition & 1 deletion Sources/MeiliSearch/Model/SearchResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class Searchable<T>: Equatable, Codable where T: Codable, T: Equatable {

/// Distribution of the given facets.
public var facetDistribution: [String: [String: Int]]?

/// Maximum & minimum stats of a numeric facet.
public var facetStats: [String: FacetStats]?

Expand Down
22 changes: 21 additions & 1 deletion Sources/MeiliSearch/Model/Setting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ public struct Setting: Codable, Equatable {
/// List of attributes used for sorting
public let sortableAttributes: [String]?

/// List of tokens that will be considered as word separators by Meilisearch.
public let separatorTokens: [String]?

/// List of tokens that will not be considered as word separators by Meilisearch.
public let nonSeparatorTokens: [String]?

/// List of words on which the segmentation will be overridden.
public let dictionary: [String]?

/// Pagination settings for the current index
public let pagination: Pagination?

// MARK: Initializers

public init(
Expand All @@ -43,7 +55,11 @@ public struct Setting: Codable, Equatable {
synonyms: [String: [String]]? = nil,
distinctAttribute: String? = nil,
filterableAttributes: [String]? = nil,
sortableAttributes: [String]? = nil
sortableAttributes: [String]? = nil,
separatorTokens: [String]? = nil,
nonSeparatorTokens: [String]? = nil,
dictionary: [String]? = nil,
pagination: Pagination? = nil
) {
self.rankingRules = rankingRules
self.searchableAttributes = searchableAttributes
Expand All @@ -53,5 +69,9 @@ public struct Setting: Codable, Equatable {
self.distinctAttribute = distinctAttribute
self.filterableAttributes = filterableAttributes
self.sortableAttributes = sortableAttributes
self.nonSeparatorTokens = nonSeparatorTokens
self.separatorTokens = separatorTokens
self.dictionary = dictionary
self.pagination = pagination
}
}
12 changes: 12 additions & 0 deletions Sources/MeiliSearch/Model/SettingResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,16 @@ public struct SettingResult: Codable, Equatable {

/// List of attributes used for sorting
public let sortableAttributes: [String]

/// List of tokens that will be considered as word separators by Meilisearch.
public let separatorTokens: [String]

/// List of tokens that will not be considered as word separators by Meilisearch.
public let nonSeparatorTokens: [String]

/// List of words on which the segmentation will be overridden.
public let dictionary: [String]

/// Pagination settings for the current index
public let pagination: Pagination
}
12 changes: 12 additions & 0 deletions Sources/MeiliSearch/Model/Task.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ public struct Task: Codable, Equatable {
/// Distinct attribute on settings actions
public let distinctAttribute: String?

/// List of tokens that will be considered as word separators by Meilisearch.
public let separatorTokens: [String]?

/// List of tokens that will not be considered as word separators by Meilisearch.
public let nonSeparatorTokens: [String]?

/// List of words on which the segmentation will be overridden.
public let dictionary: [String]?

/// Settings for index level pagination rules
public let pagination: Pagination?

}
/// Error information in case of failed update.
public let error: MeiliSearch.MSErrorResponse?
Expand Down
Loading

0 comments on commit 4913acb

Please sign in to comment.