Lucene DocValues 多值写入顺序并不能保证

Lucene DocValues 多值写入顺序并不能保证目录Lucene DocValues 多值写入顺序并不能保证1、背景2、ES和Lucene2.1、Lucene doc values字段介绍2.2、模拟写入和读取2.3、简单看下代码3、参考1、背景在工作中使用到ES 5.3.2的脚本(painless)排序时,业务逻辑较为复杂,需要获取存储的字段值列表,比如sortfield:["value3","value1","value2"]之前使用时只是判断是否存在,是布尔型判断。但新的业务需求
摘要由CSDN通过智能技术生成

Lucene DocValues 多值写入顺序并不能保证

1、背景

在工作中使用到ES 5.3.2的脚本(painless)排序时,业务逻辑较为复杂,需要获取存储的字段值列表,比如

sortfield:["value3","value1","value2"]

之前使用时只是判断是否存在,是布尔型判断。
但新的业务需求需要使用其顺序,此时测试发现脚本中获取的顺序并不是写入的数据,此时需要调研下写入顺序是否和取出后的顺序不一致,脚本使用代码示例:

if(doc.containsKey('sortfield') && doc['sortfield'].values.contains('value1')){...}

2、ES和Lucene

ES 5.3.2底层使用的是Lucene 6.4.2,其doc values也是使用的底层Lucene的实现,故需要查找Lucene的doc values实现过程。

2.1、Lucene doc values字段介绍

这里测试用到两个类型:
NumericDocValuesField:数值型多值存储
SortedDocValuesField:其他型多值存储

2.2、模拟写入和读取

maven-pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>kite-lucene-learn</artifactId>
        <groupId>kite-lucene-learn</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>lucene642</artifactId>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>compile</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-core -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>6.4.2</version>
        </dependency>
    </dependencies>
</project>
package docvalues;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedSetDocValuesField;
import org.apache.lucene.index.*;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.BytesRef;
import org.junit.Test;

import java.io.IOException;

public class TestDocValues {
   
    final static String FIELDNAME_VAL = "sortfield";
    final static String FIELDNAME_ID = "id";

    @Test
    public void testDocValuesMultiValuesSort() throws IOException {
   
        RAMDirectory ram = new RAMDirectory();
        IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer());
        IndexWriter writer = new IndexWriter(ram, config)<
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Lucene 8中去重的实现可以通过使用Facets API来完成。Facets API可以用于对搜索结果进行聚合和分组,并且可以根据字段值进行去重。 以下是使用Lucene 8进行去重的基本步骤: 1. 首先,您需要创建一个索引,并将需要去重的字段存储在索引中。 2. 接下来,使用Facets API来创建一个FacetsConfig对象,并将需要去重的字段添加到该对象中。 3. 在搜索时,您可以使用FacetsCollector类来收集搜索结果。 4. 使用FacetsCollector类的getFacetResults方法来获取聚合结果。 5. 在聚合结果中,您可以使用getTopChildren方法来获取每个字段值的文档数量,并据此进行去重。 以下是一个示例代码,演示了如何使用Lucene 8进行字段值去重: ```java // 创建索引 Directory indexDir = FSDirectory.open(Paths.get("index")); IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer()); IndexWriter writer = new IndexWriter(indexDir, config); // 创建FacetsConfig对象并添加需要去重的字段 FacetsConfig facetsConfig = new FacetsConfig(); facetsConfig.setMultiValued("fieldName", true); // 如果字段是多值的,请设置为true // 将文档添加到索引中 Document doc1 = new Document(); doc1.add(new StringField("fieldName", "value1", Field.Store.YES)); writer.addDocument(facetsConfig.build(doc1)); Document doc2 = new Document(); doc2.add(new StringField("fieldName", "value2", Field.Store.YES)); writer.addDocument(facetsConfig.build(doc2)); writer.commit(); writer.close(); // 进行搜索并去重 DirectoryReader reader = DirectoryReader.open(indexDir); IndexSearcher searcher = new IndexSearcher(reader); // 创建FacetsCollector对象 FacetsCollector facetsCollector = new FacetsCollector(); // 创建查询 Query query = new MatchAllDocsQuery(); // 执行搜索 searcher.search(query, facetsCollector); // 获取聚合结果 Facets facets = new FastTaxonomyFacetCounts(indexDir, facetsConfig, facetsCollector); FacetResult result = facets.getTopChildren(Integer.MAX_VALUE, "fieldName"); // 输出每个字段值及对应的文档数量 for (LabelAndValue labelValue : result.labelValues) { System.out.println(labelValue.label + ": " + labelValue.value); } reader.close(); indexDir.close(); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值