elasticsearch中一个field多个值如何操作

 在做项目中用到全文检索时遇到这样的需求,有个field的值是多个uuid格式的id组成的字符串,每个id之间用英文逗号分隔,在查询时如果有一个关键字和这个字符串中的一个id一样的话则要取出这个数据。这里要注意,很显然是很难对uuid组成的字符串进行切词的,而且如果uuid很多的情况下使用Lucene的模糊匹配效率也不高。于是我就想了个方案:在创建索引之前就将这个字符串分切成多个id加到同一个field上(还好是Lucene,如果是关系型数据库就不行了),而且不进行分词即可。以下就是涉及到的技术,没有多少技术含量,但是网上关于elasticsearch这方面资料少,反正我是没有查到,经过试验算是搞定了。废话少说:

         首先,在Lucene中,如果我们可以在一个Field中加入多个值,比如:

         doc.add(new Field("name","北京",Store.YES,Field.Index.NOT_ANALYZED));
    doc.add(new Field("name","新德里",Store.YES,Field.Index.NOT_ANALYZED));

    这样,当我们针对“name”这个field进行搜索时,如果搜索的关键字是“北京”或者“新德里”则当前这个Document都会被搜索到,这个是Lucene不同于关系型数据库的地方。

    那么基于Lucene上的分布式全文索引elasticsearch如何做到呢?经过试验可以使用类似于如下的方式创建索引:

    XContentBuilder doc = XContentFactory.jsonBuilder(); //整个每次循环都需要创建一个,否则会在startObject时报空指针
    //添加属性,相当于添加表的字段的值
    doc.startObject();
    //获取id,如果存在的话
    String idValue = null;
    for(String field : contextObject.keySet()) {
       Object[] values = contextObject.get(field);
       //如果是同一个field下多个值,则全部加入到同一个field下
       if(null != values && values.length > 1) {
          doc.array(field, values);
       } else {
          String formatValue = this.formatInsertData(values);//格式化处理值
          try {
            if(StringUtils.isNotEmpty(idFieldName) && idFieldName.equals(field)) {
              idValue = formatValue;
            }
            doc.field(field, formatValue);
          } catch (IOException e) {
            this.logger.error(e.getMessage());
            return false;
          }          
      }            
    }
    doc.endObject();

    上边标红的部分就是要使用的API方式,同时在进行数据检索时也要注意,这样添加的数据,搜索结果要强转成List类型的,比如我们这里是List<String>。

    

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值