记录一次solr自定义函数编写及使用的过程

简介: solr基本查询已经可以满足大多数查询场景,不过作为一款成熟的搜索引擎solr也可以支持编写自定义函数udf并在查询中使用以应对各种复杂的查询场景。

背景:目前我们solr中存储的数据因为很多属性字段的不确定性,选择将数据在一个大字段中合并。如下格式中attr字段代表着一个不确定的属性字段,可能为身高、体重、性别等,也可能为页码、出版方、售价等

{

“id”:“1”

“attr”:“180,80,男”

“type”:“person”

},

{

“id”:“2”

“attr”:“50,人民出版社,50¥”

“type”:“book”

}

针对这种近期产品提出一个要针对人类按照身高排序,书籍类按照售价排序。这种需求怎么搞呢?身高属性已经跟其他属性混为一个字段,常规排序怕是行不通。

思路:既然常规思路行不通,我们想能不能通过函数截取的方式通过比对该字符串指定位置来实现排序呢?下面直接上代码

代码:首先需要定义两个类SubStrValueSourceParser

import org.apache.commons.lang.StringUtils;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.FunctionQParser;
import org.apache.solr.search.SyntaxError;
import org.apache.solr.search.ValueSourceParser;
public class SubStrValueSourceParser extends ValueSourceParser {
    public SubStrValueSourceParser() {
        super();
    }
    @Override
    public ValueSource parse(FunctionQParser fp) throws SyntaxError {
        String fieldStr = fp.parseArg();//第一个参数
        String bgnLocation = fp.parseArg();//第二个参数数组下标
        ValueSource location = getValueSource(fp, fieldStr);//取得函数调用时指定字段值
//将参数及需要的文档的值传给自定义的ValueSource方法,打分规则在自定义的ValueSource中定制
        SubStrValueSource stringFieldSource = new SubStrValueSource(location, bgnLocation);
        return stringFieldSource;
    }
//该方法是根据字段名,从FunctionQParser得到文档该字段的相关信息
    public ValueSource getValueSource(FunctionQParser fp, String arg) {
        if (arg == null)
            return null;
        SchemaField f = fp.getReq().getSchema().getField(arg);
        return f.getType().getValueSource(f, fp);
    }
}
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
import org.apache.lucene.queries.function.docvalues.FloatDocValues;
import org.apache.lucene.queries.function.docvalues.IntDocValues;
import org.apache.lucene.queries.function.docvalues.StrDocValues;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class SubStrValueSource extends ValueSource {
    private ValueSource attr13;//需要进行格式转换的字段
    private String location;
    //通过构造方法获取字段
    public SubStrValueSource(ValueSource attr13, String location) {
        this.attr13 = attr13;
        this.location = location;
    }
    @Override
    public FunctionValues getValues(Map map, LeafReaderContext leafReaderContext) throws IOException {
        final FunctionValues fieldValues = attr13.getValues(map,
                leafReaderContext);//获取attr13的值
        return new DoubleDocValues(this) {
            @Override
            public double doubleVal(int i) throws IOException {
                String fieldStr = null;
                Double retValue = 0.00;
                //若要被转化的值为空或者为空字符串则返回0
                if (fieldValues.strVal(i) == null || "".equals(fieldValues.strVal(i))) {
                } else {
                    fieldStr = fieldValues.strVal(i);
                    String[] vList = fieldStr.split(",");
                    //若实际数组长度小于下标则不处理直接返回0,若大于或等于下标则截取对应位置数据
                    if (vList.length < Integer.parseInt(location) + 1) {
                    } else {
                        String content = vList[Integer.parseInt(location)];
                        retValue = Double.parseDouble(content);
                    }
                }
                return retValue;
            }
        };
    }
    @Override
    public boolean equals(Object o) {
        return true;
    }
    @Override
    public int hashCode() {
        return 0;
    }
    @Override
    public String description() {
        return name();
    }
    public String name() {
        return "subStr";
    }
}

发布:代码逻辑编写完毕后打成jar包并按照如下步骤操作

  1. 在solr安装目录下dist目录中将打好的jar包放进去
  2. 在solrconfig.xml中新增以下配置

<lib dir="${solr.install.dir:../../../..}/dist/" regex="com.tl.solr.*\.jar" />

<valueSourceParser name="subStr"

                       class="SubStrValueSourceParser" />

搞定之后重启服务生效

使用效果:

1646278833(1).png

1646278927(1).png


相关文章
|
运维 Linux Windows
【计算巢】幻兽帕鲁服务器如何设置定时备份存档
计算巢针对幻兽帕鲁服务器,提供给了定时备份存档的功能,会在设定的频率下,定时将存档文件备份到目标文件夹下,有助于解决存档丢失和坏档的问题。
4401 1
|
自然语言处理 索引 算法
HanLP分词命名实体提取详解
文本挖掘是抽取有效、新颖、有用、可理解的、散布在文本文件中的有价值知识,并且利用这些知识更好地组织信息的过程。对于文本来说,由于语言组织形式各异,表达方式多样,文本里面提到的很多要素,如人名、手机号、组织名、地名等都称之为实体。
7838 0
|
Docker 容器
容器的日志
【10月更文挑战第31天】
602 68
|
传感器 搜索推荐 数据处理
智能织物:纺织品中的科技革新
【10月更文挑战第13天】智能织物通过融合传感器、微处理器和无线通信技术,赋予传统纺织品更多功能性和智能化属性,正从科幻走向现实。本文探讨其原理、类型及应用,如健康监测、运动辅助和环境适应等,并展望其未来发展趋势,包括多功能集成、可穿戴设备融合、环保可持续及个性化定制,引领纺织品领域的深刻变革。
|
Shell 网络安全 开发工具
gitbash 安装与使用
gitbash 安装教程
589 1
|
SQL 数据库 数据库管理
数据库SQL函数应用技巧与方法
在数据库管理中,SQL函数是处理和分析数据的强大工具
|
存储 弹性计算 云计算
深入理解云计算:探索IaaS、PaaS和SaaS服务模型
云计算作为当代信息技术领域的关键驱动力,通过提供弹性计算资源和灵活的服务模型,极大地改变了企业和个人的计算方式。本文深入探讨了云计算的基础概念,着重介绍了三种主要的云计算服务模型:IaaS、PaaS和SaaS。
1607 0
|
设计模式 人工智能 JSON
一文掌握大模型提示词技巧:从战略到战术
本文将用通俗易懂的语言,带你从战略(宏观)和战术(微观)两个层次掌握大模型提示词的常见技巧,真正做到理论和实践相结合,占领 AI 运用的先机。
240771 5
|
缓存 前端开发 JavaScript
【最全最详细】publiccms使用教程
【最全最详细】publiccms使用教程
|
存储
数据结构学习记录——什么是堆(优先队列、堆的概念、最大堆最小堆、优先队列的完全二叉树表示、堆的特性、堆的抽象数据类型描述)
数据结构学习记录——什么是堆(优先队列、堆的概念、最大堆最小堆、优先队列的完全二叉树表示、堆的特性、堆的抽象数据类型描述)
447 2

热门文章

最新文章