Elasticsearch 和 OpenSearch Java SDK 通用方法实现

问题描述 投票:0回答:1

假设我有一个支持 Elasticsearch 或 OpenSearch 服务的应用程序。我有一个

SearchClient
接口,可实现特定客户端(即 ES 或 OS)。每个方法都实现相同的逻辑,只是类型不同。

Java 中是否有可能以及推荐的方法来消除重复代码并集中核心逻辑?我知道有关于提取最低共同祖先的建议,但在这种情况下,它最终会是

Object
。我还探索了使用 Adapter 类的可能性,但最终处于适配器的返回类型与客户端类型相关的相同位置。

代码

public interface SearchClient {
[...]
  void update(
      String indexName,
      Pair<String, String> fieldAndValue,
      Pair<String, Map<String, Object>> updates);
[...]
}
public class ElasticSearchClient implements SearchClient {
[...]
  @Override
  public void update(
      String indexName,
      Pair<String, String> fieldAndValue,
      Pair<String, Map<String, Object>> updates) {
    if (isClientAvailable) {
      UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
      updateByQueryRequest.setQuery(
          new MatchQueryBuilder(fieldAndValue.getKey(), fieldAndValue.getValue())
              .operator(Operator.AND));
      Script script =
          new Script(
              ScriptType.INLINE,
              Script.DEFAULT_SCRIPT_LANG,
              updates.getKey(),
              JsonUtils.getMap(updates.getValue() == null ? new HashMap<>() : updates.getValue()));
      updateByQueryRequest.setScript(script);
      updateElasticSearchByQuery(updateByQueryRequest);
    }
  }
}
[...]
public class OpenSearchClient implements SearchClient {
[...]
  @Override
  public void update(
      String indexName,
      Pair<String, String> fieldAndValue,
      Pair<String, Map<String, Object>> updates) {
    if (isClientAvailable) {
      UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
      updateByQueryRequest.setQuery(
          new MatchQueryBuilder(fieldAndValue.getKey(), fieldAndValue.getValue())
              .operator(Operator.AND));
      Script script =
          new Script(
              ScriptType.INLINE,
              Script.DEFAULT_SCRIPT_LANG,
              updates.getKey(),
              JsonUtils.getMap(updates.getValue() == null ? new HashMap<>() : updates.getValue()));
      updateByQueryRequest.setScript(script);
      updateElasticSearchByQuery(updateByQueryRequest);
    }
  }
}
[...]
java elasticsearch design-patterns opensearch
1个回答
0
投票

为了避免 ElasticSearchClientOpenSearchClient 类中的代码重复,您可以将公共逻辑提取到单独的类或方法中。

具体操作方法如下:

  1. 创建一个类(我们称之为 SearchClientCommon)。
  2. 在 (SearchClientCommon) 类中编写公共逻辑。
  3. 将 SearchClientCommon 实例注入到您的 ElasticSearchClientOpenSearchClient 类中。

这是一个示例实现:

SearchClient界面(无变化)

public interface SearchClient {
   void update(String indexName, Pair<String, String> fieldAndValue, Pair<String, Map<String, Object>> updates);
}

ElasticSearchClient 类(添加了 SearchClientCommon 实例)

public class ElasticSearchClient implements SearchClient {
   private final SearchClientCommon common;

   public ElasticSearchClient(SearchClientCommon common) {
       this.common = common;
   }

   @Override
   public void update(String indexName, Pair<String, String> fieldAndValue, Pair<String, Map<String, Object>> updates) {
       if (isClientAvailable) {
           common.update(indexName, fieldAndValue, updates);
       }
   }
}

OpenSearchClient类(添加了SearchClientCommon实例)

public class OpenSearchClient implements SearchClient {
   private final SearchClientCommon common;

   public OpenSearchClient(SearchClientCommon common) {
       this.common = common;
   }

   @Override
   public void update(String indexName, Pair<String, String> fieldAndValue, Pair<String, Map<String, Object>> updates) {
       if (isClientAvailable) {
           common.update(indexName, fieldAndValue, updates);
       }
    }
}

SearchClientCommon类(添加了公共逻辑)

public class SearchClientCommon {
   public void update(String indexName, Pair<String, String> fieldAndValue, Pair<String, Map<String, Object>> updates) {
       UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
       updateByQueryRequest.setQuery(
            new MatchQueryBuilder(fieldAndValue.getKey(), fieldAndValue.getValue())
                    .operator(Operator.AND));
       Script script =
            new Script(
                    ScriptType.INLINE,
                    Script.DEFAULT_SCRIPT_LANG,
                    updates.getKey(),
                    JsonUtils.getMap(updates.getValue() == null ? new HashMap<>() : updates.getValue()));
       updateByQueryRequest.setScript(script);
       updateElasticSearchByQuery(updateByQueryRequest);
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.