You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在EHCache的字符串列表值中高效搜索并返回Java对象?

在EHCache中优化列表属性的搜索方案

问题场景

缓存结构为:键是ID,值是包含ArrayList<String>类型邮箱列表的VzdData对象,需根据邮箱地址搜索对应的完整VzdData实例。当前通过将邮箱列表拼接为分号分隔字符串,再用ilike模糊匹配实现,寻求更优方案。

当前实现代码

属性提取器与缓存配置

public static class EMailAttributeExtractor implements AttributeExtractor {

    public Object attributeFor(Element element) {
         VzdData vzdData = ((VzdData) element.getObjectValue());
        return String.join(";", vzdData.getServiceData().getMail());
    }

    @Override
    public Object attributeFor(Element element, String attributeName) throws AttributeExtractorException {
      return this.attributeFor(element);
    }
}

Searchable searchable = new Searchable();
searchable.addSearchAttribute(new SearchAttribute().name("email").className(EMailAttributeExtractor.class.getName()));
searchable.setAllowDynamicIndexing(true);

查询方法

public VzdData getVzdDatabyEMail(String email) throws VZDException {
 log.entry(email);

     VzdData vzdData = null;
    
     Attribute<String> emailSearchAttribute = this.cache.getSearchAttribute("email");
    Query query = this.cache.createQuery().addCriteria(emailSearchAttribute.ilike("*" + email + "*"));
    query.includeValues();
    
    Results results = query.execute();
    List<Result> resultList = results.all();
            
    return log.exit(vzdData);
}

优化方案:利用EHCache集合类型属性的原生搜索支持

EHCache的搜索API原生支持对集合类型属性执行精确匹配,无需拼接字符串,性能和准确性更优。

1. 修改属性提取器,直接返回邮箱列表

无需将列表拼接为字符串,直接返回List<String>类型的邮箱集合:

public static class EMailAttributeExtractor implements AttributeExtractor {
    @Override
    public Object attributeFor(Element element) {
        VzdData vzdData = ((VzdData) element.getObjectValue());
        return vzdData.getServiceData().getMail(); // 返回原列表集合
    }

    @Override
    public Object attributeFor(Element element, String attributeName) throws AttributeExtractorException {
        return this.attributeFor(element);
    }
}

2. 调整查询逻辑,使用contains精确匹配

替换ilike为contains条件,实现集合元素的精确匹配:

public VzdData getVzdDatabyEMail(String email) throws VZDException {
    log.entry(email);
    VzdData vzdData = null;
    
    Attribute<List<String>> emailSearchAttribute = this.cache.getSearchAttribute("email");
    // 使用contains条件匹配集合中的精确邮箱
    Query query = this.cache.createQuery().addCriteria(emailSearchAttribute.contains(email));
    query.includeValues();
    
    Results results = query.execute();
    List<Result> resultList = results.all();
    
    // 处理匹配结果(示例取第一个匹配项)
    if (!resultList.isEmpty()) {
        vzdData = (VzdData) resultList.get(0).getValue();
    }
    
    return log.exit(vzdData);
}

优化优势

  • 性能提升:避免字符串拼接开销,contains基于集合索引匹配,比模糊ilike效率更高;
  • 结果准确:不会出现模糊匹配导致的误命中(如不会将test@test.de与test这类子串匹配);
  • 逻辑简洁:无需处理通配符与字符串拼接,代码更直观。

如果需要支持邮箱的模糊匹配(如按域名搜索),可以进一步拆分邮箱属性(如提取域名作为单独搜索属性),但精确匹配单个邮箱时,上述方案为最优解。

内容的提问来源于stack exchange,提问作者Tobias Wolf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 15:54:59