ElasticSwift

Build Status codecov Swift Version SwiftPM Compatible Supported Platforms CocoaPods Compatible

项目状态

本项目正在积极开发中,随着项目进展将提供更多信息。

如果您想贡献代码,欢迎提交 pull request。

项目目标

我们的目标是创建一个非常 Swifty 且高性能的 elasticsearch 客户端。

高性能意味着在 100 毫秒内提供最终用户的响应,不包括 elasticsearch 处理请求的时间。

安装

CocoaPods

CocoaPods 是 Cocoa 项目的依赖管理器。您可以使用以下命令安装它

$ gem install cocoapods

需要 CocoaPods 1.6.0+ 才能构建 ElasticSwift。

要使用 CocoaPods 将 ElasticSwift 集成到您的 Xcode 项目中,请在您的 Podfile 文件中指定它

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'ElasticSwift', '~> 1.0.0-beta.1'
    pod 'ElasticSwiftCore', '~> 1.0.0-beta.1'
    pod 'ElasticSwiftQueryDSL', '~> 1.0.0-beta.1'
    pod 'ElasticSwiftCodableUtils', '~> 1.0.0-beta.1'
    pod 'ElasticSwiftNetworking', '~> 1.0.0-beta.1'
end

注意:- ElasticSwiftNetworkingNIO 不可用作 pod

然后,运行以下命令

$ pod install

Swift Package Manager

Swift Package Manager 是一个用于自动化 Swift 代码分发的工具,并已集成到 swift 编译器中。它还处于早期开发阶段,但 ElasticSwift 确实支持在受支持的平台上使用它。

一旦您设置了 Swift 包,添加 ElasticSwift 作为依赖项就像将其添加到您的 Package.swift 文件的 dependencies 值中一样简单。

dependencies: [
    .package(url: "https://github.com/pksprojects/ElasticSwift.git", from: "1.0.0-beta.1")
]

然后将适当的 ElasticSwift 模块添加到您的目标依赖项中。添加目标依赖项的语法在 Swift 版本之间略有不同。例如,如果您想依赖 ElasticSwiftElasticSwiftCore 模块,请指定以下依赖项

Swift 5.0 和 5.1 (swift-tools-version:5.[01])

    dependencies: ["ElasticSwift", "ElasticSwiftCore"]

Swift 5.2 (swift-tools-version:5.2)

    dependencies: [.product(name: "ElasticSwift", package: "elastic-swift"),
                   .product(name: "ElasticSwiftCore", package: "elastic-swift")]

用法

客户端

创建 SettingsElasticClient

使用 ElasticSwiftNetworking (基于 URLSession 的实现)

import ElasticSwift
import ElasticSwiftNetworking

var settings = Settings(forHost: "https://:9200", adaptorConfig: URLSessionAdaptorConfiguration.default) // Creates default settings for client
var client = ElasticClient(settings: settings) // Creates client with specified settings

使用 ElasticSwiftNetworkingNIO (基于 SwiftNIO/AsyncHTTPClient 的实现)

import ElasticSwift
import ElasticSwiftNetworkingNIO

var settings = Settings(forHost: "https://:9200", adaptorConfig: AsyncHTTPClientAdaptorConfiguration.default) // Creates default settings for client
var client = ElasticClient(settings: settings) // Creates client with specified settings

添加 Elasticsearch 凭据

let cred = BasicClientCredential(username: "elastic", password: "elastic")
let settings = Settings(forHost: "https://:9200", withCredentials: cred, adaptorConfig: AsyncHTTPClientAdaptorConfiguration.default)

使用 ElasticSwiftNetworking 时配置 SSL

let certPath = "/path/to/certificate.der"
let sslConfig = SSLConfiguration(certPath: certPath, isSelf: true)
let adaptorConfig = URLSessionAdaptorConfiguration(sslConfig: sslConfig)
let settings = Settings(forHosts: ["https://samplehost:port"], withCredentials: cred, adaptorConfig: adaptorConfig)

索引

创建和删除索引

func createHandler(_ result: Result<CreateIndexResponse, Error>) -> Void {
    switch result {
        case .failure(let error):
            print("Error", error)
        case .success(let response):
            print("Response", response)
    }
}

// creating index
let createIndexRequest = CreateIndexRequest("indexName")
client.indices.create(createIndexRequest, completionHandler: createHandler) // executes request

// delete index
func deleteHandler(_ result: Result<AcknowledgedResponse, Error>) -> Void {
    switch result {
        case .failure(let error):
            print("Error", error)
        case .success(let response):
            print("Response", response)
    }
}

let deleteIndexRequest = DeleteIndexRequest("indexName")
client.indices.delete(deleteIndexRequest, completionHandler: deleteHandler) // executes request

文档

文档 CRUD

class MyClass: Codable, Equatable {
  var myField: String?
}

// index document
func indexHandler(_ result: Result<IndexResponse, Error>) -> Void {
    switch result {
        case .failure(let error):
            print("Error", error)
        case .success(let response):
            print("Response", response)
    }
}

let mySource = MyClass()
mySource.myField = "My value"

let indexRequest = try IndexRequestBuilder<MyClass>()
        .set(index: "indexName")
        .set(type: "type")
        .set(id: "id")
        .set(source: mySource)
        .build()

client.index(indexRequest, completionHandler: indexHandler)

// get document
func getHandler(_ result: Result<GetResponse<MyClass>, Error>) -> Void {
    switch result {
        case .failure(let error):
            print("Error", error)
        case .success(let response):
            print("Response", response)
    }
}

let getRequest = try GetRequestBuilder()
    .set(id: "id")
    .set(index: "indexName")
    .set(type: "type")
    .build()

client.get(getRequest, completionHandler: getHandler)

// delete document
func deleteHandler(_ result: Result<DeleteResponse, Error>) -> Void {
    switch result {
        case .failure(let error):
            print("Error", error)
        case .success(let response):
            print("Response", response)
    }
}

let deleteRequest = try DeleteRequestBuilder()
    .set(index: "indexName")
    .set(type: "type")
    .set(id: "id")
    .build()

client.delete(deleteRequest, completionHandler: deleteHandler)

查询

目前并非所有 QueryBuilders 都可用。未来的版本将增加对更多 QueryBuilders 的支持。查看下面了解详情

let builder = QueryBuilders.boolQuery()
let mustMatch = try QueryBuilders.matchQuery().set(field: "fieldName").set(value: "value").build()
let mustNotMatch = try QueryBuilders.matchQuery().set(field: "someFieldName").set(value: "value").build()
builder.must(query: mustMatch)
builder.mustNot(query: mustNotMatch)
let boolQuery = try builder.build()

搜索

创建简单的搜索请求。

func handler(_ result: Result<SearchResponse<Message>, Error>) -> Void {
    switch result {
        case .failure(let error):
            print("Error", error)
        case .success(let response):
            print("Response", response)
    }
}

let queryBuilder = QueryBuilders.boolQuery()
let match = try QueryBuilders.matchQuery().set(field: "msg").set(value: "Message").build() 
queryBuilder.must(query: match)

let query =  try queryBuilder.build()

let sort =  SortBuilders.fieldSort("msg") // use "msg.keyword" as field name in case of text field
    .set(order: .asc)
    .build()

let request = try SearchRequestBuilder()
        .set(indices: "indexName")
        .set(types: "type")
        .set(query: query)
        .add(sort: sort)
        .build()

client.search(request, completionHandler: handler)

QueryDSL

下表列出了所有可用的搜索查询,以及它们在 QueryBuilders 实用程序类中对应的 QueryBuilder 类名和辅助方法名。

搜索查询 QueryBuilder 类 QueryBuilders 中的方法
ConstantScoreQuery ConstantScoreQueryBuilder QueryBuilders.constantScoreQuery()
BoolQuery BoolQueryBuilder QueryBuilders.boolQuery()
DisMaxQuery DisMaxQueryBuilder QueryBuilders.disMaxQuery()
FunctionScoreQuery FunctionScoreQueryBuilder QueryBuilders.functionScoreQuery()
BoostingQuery BoostingQueryBuilder QueryBuilders.boostingeQuery()
MatchQuery MatchQueryBuilder QueryBuilders.matchQuery()
MatchPhraseQuery MatchPhraseQueryBuilder QueryBuilders.matchPhraseQuery()
MatchPhrasePrefixQuery MatchPhrasePrefixQueryBuilder QueryBuilders.matchPhrasePrefixQuery()
MultiMatchQuery MultiMatchQueryBuilder QueryBuilders.multiMatchQuery()
CommonTermsQuery CommonTermsQueryBuilder QueryBuilders.commonTermsQuery()
QueryStringQuery QueryStringQueryBuilder QueryBuilders.queryStringQuery()
SimpleQueryStringQuery SimpleQueryStringQueryBuilder QueryBuilders.simpleQueryStringQuery()
MatchAllQuery MatchAllQueryBuilder QueryBuilders.matchAllQuery()
MatchNoneQuery MatchNoneQueryBuilder QueryBuilders.matchNoneQuery()
TermQuery TermQueryBuilder QueryBuilders.termQuery()
TermsQuery TermsQueryBuilder QueryBuilders.termsQuery()
RangeQuery RangeQueryBuilder QueryBuilders.rangeQuery()
ExistsQuery ExistsQueryBuilder QueryBuilders.existsQuery()
PrefixQuery PrefixQueryBuilder QueryBuilders.prefixQuery()
WildCardQuery WildCardQueryBuilder QueryBuilders.wildCardQuery()
RegexpQuery RegexpQueryBuilder QueryBuilders.regexpQuery()
FuzzyQuery FuzzyQueryBuilder QueryBuilders.fuzzyQuery()
TypeQuery TypeQueryBuilder QueryBuilders.typeQuery()
IdsQuery IdsQueryBuilder QueryBuilders.idsQuery()
NestedQuery NestedQueryBuilder QueryBuilders.nestedQuery()
HasChildQuery HasChildQueryBuilder QueryBuilders.hasChildQuery()
HasParentQuery HasParentQueryBuilder QueryBuilders.hasParentQuery()
ParentIdQuery ParentIdQueryBuilder QueryBuilders.parentIdQuery()
GeoShapeQuery GeoShapeQueryBuilder QueryBuilders.geoShapeQuery()
GeoBoundingBoxQuery GeoBoundingBoxQueryBuilder QueryBuilders.geoBoundingBoxQuery()
GeoDistanceQuery GeoDistanceQueryBuilder QueryBuilders.geoDistanceQuery()
GeoPolygonQuery GeoPolygonQueryBuilder QueryBuilders.geoPolygonQuery()
MoreLikeThisQuery MoreLikeThisQueryBuilder QueryBuilders.moreLikeThisQuery()
ScriptQuery ScriptQueryBuilder QueryBuilders.scriptQuery()
PercolateQuery PercoloteQueryBuilder QueryBuilders.percolateQuery()
WrapperQuery WrapperQueryBuilder QueryBuilders.wrapperQuery()
SpanTermQuery SpanTermQueryBuilder QueryBuilders.spanTermQuery()
SpanMultiTermQuery SpanMultiTermQueryBuilder sQueryBuilders.panMultiTermQueryBuilder()
SpanFirstQuery SpanFirstQueryBuilder QueryBuilders.spanFirstQuery()
SpanNearQuery SpanNearQueryBuilder sQueryBuilders.panNearQuery()
SpanOrQuery SpanOrQueryBuilder QueryBuilders.spanOrQuery()
SpanNotQuery SpanNotQueryBuilder QueryBuilders.spanNotQuery()
SpanContainingQuery SpanContainingQueryBuilder QueryBuilders.spanContainingQuery()
SpanWithinQuery SpanWithinQueryBuilder QueryBuilders.spanWithinQuery()
SpanFieldMaskingQueryBuilder SpanFieldMaskingQueryBuilder QueryBuilders.fieldMaskingSpanQuery()