初始化

This commit is contained in:
2026-02-22 18:55:40 +08:00
commit 8392cdd861
496 changed files with 45020 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2023-2026, Easy-Agents (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.easyagents.engine.es;
public class ESConfig {
private String host;
private String userName;
private String password;
private String indexName;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
}

View File

@@ -0,0 +1,223 @@
package com.easyagents.engine.es;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.core.bulk.IndexOperation;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.easyagents.core.document.Document;
import com.easyagents.search.engine.service.DocumentSearcher;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.*;
public class ElasticSearcher implements DocumentSearcher {
private static final Logger LOG = LoggerFactory.getLogger(ElasticSearcher.class);
private final ESConfig esConfig;
public ElasticSearcher(ESConfig esConfig) {
this.esConfig = esConfig;
}
// 忽略 SSL 的 client 构建逻辑
private RestClient buildRestClient() throws NoSuchAlgorithmException, KeyManagementException {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials(esConfig.getUserName(), esConfig.getPassword()));
return RestClient.builder(HttpHost.create(esConfig.getHost()))
.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setSSLContext(sslContext);
httpClientBuilder.setSSLHostnameVerifier((hostname, session) -> true);
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
return httpClientBuilder;
})
.build();
}
/**
* 添加文档到Elasticsearch
*/
@Override
public boolean addDocument(Document document) {
if (document == null || document.getContent() == null) {
return false;
}
RestClient restClient = null;
ElasticsearchTransport transport = null;
try {
restClient = buildRestClient();
transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
ElasticsearchClient client = new ElasticsearchClient(transport);
Map<String, Object> source = new HashMap<>();
source.put("id", document.getId());
source.put("content", document.getContent());
if (document.getTitle() != null) {
source.put("title", document.getTitle());
}
String documentId = document.getId().toString();
IndexOperation<?> indexOp = IndexOperation.of(i -> i
.index(esConfig.getIndexName())
.id(documentId)
.document(JsonData.of(source))
);
BulkOperation bulkOp = BulkOperation.of(b -> b.index(indexOp));
BulkRequest request = BulkRequest.of(b -> b.operations(Collections.singletonList(bulkOp)));
BulkResponse response = client.bulk(request);
return !response.errors();
} catch (Exception e) {
LOG.error(e.getMessage(), e);
return false;
} finally {
closeResources(transport, restClient);
}
}
@Override
public List<Document> searchDocuments(String keyword, int count) {
RestClient restClient = null;
ElasticsearchTransport transport = null;
try {
restClient = buildRestClient();
transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
ElasticsearchClient client = new ElasticsearchClient(transport);
SearchRequest request = SearchRequest.of(s -> s
.index(esConfig.getIndexName())
.size(count)
.query(q -> q
.match(m -> m
.field("title")
.field("content")
.query(keyword)
)
)
);
SearchResponse<Document> response = client.search(request, Document.class);
List<Document> results = new ArrayList<>();
response.hits().hits().forEach(hit -> results.add(hit.source()));
return results;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
return Collections.emptyList();
} finally {
closeResources(transport, restClient);
}
}
@Override
public boolean deleteDocument(Object id) {
if (id == null) {
return false;
}
RestClient restClient = null;
ElasticsearchTransport transport = null;
try {
restClient = buildRestClient();
transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
ElasticsearchClient client = new ElasticsearchClient(transport);
DeleteRequest request = DeleteRequest.of(d -> d
.index(esConfig.getIndexName())
.id(id.toString())
);
DeleteResponse response = client.delete(request);
return response.result() == co.elastic.clients.elasticsearch._types.Result.Deleted;
} catch (Exception e) {
LOG.error("Error deleting document with id: " + id, e);
return false;
} finally {
closeResources(transport, restClient);
}
}
@Override
public boolean updateDocument(Document document) {
if (document == null || document.getId() == null) {
return false;
}
RestClient restClient = null;
ElasticsearchTransport transport = null;
try {
restClient = buildRestClient();
transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
ElasticsearchClient client = new ElasticsearchClient(transport);
UpdateRequest<Document, Object> request = UpdateRequest.of(u -> u
.index(esConfig.getIndexName())
.id(document.getId().toString())
.doc(document)
);
UpdateResponse<Document> response = client.update(request, Object.class);
return response.result() == co.elastic.clients.elasticsearch._types.Result.Updated;
} catch (Exception e) {
LOG.error("Error updating document with id: " + document.getId(), e);
return false;
} finally {
closeResources(transport, restClient);
}
}
private void closeResources(AutoCloseable... closeables) {
for (AutoCloseable closeable : closeables) {
try {
if (closeable != null)
closeable.close();
} catch (Exception e) {
LOG.error("Error closing resource", e);
}
}
}
}

View File

@@ -0,0 +1,42 @@
package com.easyagents.search.engines.es;
import com.easyagents.core.document.Document;
import com.easyagents.engine.es.ESConfig;
import com.easyagents.engine.es.ElasticSearcher;
import java.math.BigInteger;
import java.util.List;
public class ElasticSearcherTest {
public static void main(String[] args) throws Exception {
// 创建工具类实例 (忽略SSL证书如果有认证则提供用户名密码)
ESConfig searcherConfig = new ESConfig();
searcherConfig.setHost("https://127.0.0.1:9200");
searcherConfig.setUserName("elastic");
searcherConfig.setPassword("elastic");
searcherConfig.setIndexName("aiknowledge");
ElasticSearcher esUtil = new ElasticSearcher(searcherConfig);
Document document1 = new Document();
document1.setContent("平台客服工具:是指拼多多平台开发并向商家提供的功能或工具,商家通过其专属账号登录平台客服工具后,可以与平台消费者取得\\n\" +\n" +
" \"联系并为消费者提供客户服务");
document1.setId(BigInteger.valueOf(1));
esUtil.addDocument(document1);
Document document2 = new Document();
document2.setId(2);
document2.setContent("document 2 的内容");
document2.setTitle("document 2");
esUtil.addDocument(document2);
System.out.println("查询开始--------");
List<Document> res = esUtil.searchDocuments("客服");
res.forEach(System.out::println);
System.out.println("查询结束--------");
document1.setTitle("document 3");
esUtil.updateDocument(document1);
// esUtil.deleteDocument(1);
}
}