当前位置: 首页 > 知识库问答 >
问题:

Lucene文档与Java ArrayList

百里嘉泽
2023-03-14

我有一组数据:ID、名称和与ID相关联的ArrayList。我希望将这些数据存储在Lucene文档中。搜索将基于Id和姓名。不应对列表进行索引。

我如何为“某些列表”做类似的事情?

共有1个答案

钱朝明
2023-03-14

你可以用Storedfield。

一个简单的aproach可能是序列化列表。下面是一个示例代码:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Random;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class LuceneTest {

    public static byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream(200000);
        ObjectOutputStream os = new ObjectOutputStream(bos);
        os.writeObject(obj);
        os.close();
        return bos.toByteArray();
    }

    public static Object unserialize(byte[] bytes) throws ClassNotFoundException, IOException {
        ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(bytes));
        Object result = is.readObject();
        is.close();
        return result;
    }

    public static void index() {
        String indexPath = "index";
        try {
            System.out.println("Indexing to directory '" + indexPath + "'...");
            Directory dir = FSDirectory.open(Paths.get(indexPath));
            Analyzer analyzer = new StandardAnalyzer();
            IndexWriterConfig iwc = new IndexWriterConfig(analyzer);

            iwc.setOpenMode(OpenMode.CREATE);

            IndexWriter writer = new IndexWriter(dir, iwc);

            for (int i = 0; i < 100; i++) {
                Document doc = new Document();
                String id = "id" + i;
                String name = "jack " + i;
                ArrayList<Object> someList = new ArrayList<>();
                someList.add(id + " => " + name);
                someList.add("index" + i);

                doc.add(new StringField("Id", id, Field.Store.YES));
                doc.add(new TextField("name", name, Field.Store.YES));
                doc.add(new StoredField("list", serialize(someList)));
                writer.addDocument(doc);
            }

            writer.close();
        } catch (IOException e) {
            System.out.println(" caught a " + e.getClass() + "\n with message: " + e.getMessage());
        }
    }

    public static void search() {
        String index = "index";
        String field = "name";
        int hitsPerPage = 10;
        try {
            IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));
            IndexSearcher searcher = new IndexSearcher(reader);
            Analyzer analyzer = new StandardAnalyzer();

            QueryParser parser = new QueryParser(field, analyzer);

            Random rnd = new Random();
            for (int i = 0; i < 10; i++) {
                int randIndex = rnd.nextInt(100);

                String nameQuery = "" + randIndex;
                Query query = parser.parse(nameQuery);
                System.out.println("Searching for: " + query.toString(field));

                TopDocs results = searcher.search(query, hitsPerPage);
                ScoreDoc[] hits = results.scoreDocs;

                for (ScoreDoc scoreDoc : hits) {
                    Document doc = searcher.doc(scoreDoc.doc);
                    String id = doc.get("Id");
                    String name = doc.get("name");
                    ArrayList<Object> list = (ArrayList<Object>) unserialize(doc.getBinaryValue("list").bytes);
                    System.out.println("id: " + id + " name: " + name + " list: " + list);
                }
                System.out.println();
            }
            reader.close();
        } catch (Exception e) {
            System.out.println(" caught a " + e.getClass() + "\n with message: " + e.getMessage());
        }
    }

    public static void main(String[] args) {
        index();
        search();
    }
}

 类似资料:
  • Lucene 是一个基于 Java 的开源搜索库。 它非常受欢迎,也是一个快速搜索库。它在基于 Java 的应用程序中用于以非常简单和有效的方式向任何类型的应用程序添加文档搜索功能。

  • 问题内容: Lucene是否提供增强新文档的方法? 例如,假设Lucene文档包含日期字段。是否有可能在用户不以任何方式更改其查询的情况下,以更高的分数展示最新的文档? 我不想诉诸粗略的“按日期排序”解决方案,因为它将完全取消评分算法。 问题答案: 将文档放入索引时,请使用Document.setBoost(float value)。 您可以不断地重新调整现有文档上的值,或者具有随日期增加的浮点值

  • null 完整代码:

  • Lucene是一个反向索引系统,据我所知,它的强大之处在于它只会将查询与至少匹配令牌的文档进行比较。 与将查询与每个文档进行比较的简单方法相比(即使是那些没有提到查询中存在的任何标记的文档),这是一个很大的好处。 例如,如果我有索引文档: 在我看来,搜索查询:“你好世界”,只会查看索引文档D1和D2,并跳过D3,这节省了时间。 这样做正确吗? 现在,我试图计算文档之间的余弦相似度。输入查询将是一个

  • 问题内容: 现在已经苦了两天,只是不能删除文件 在这里,我将放置将进行测试的代码,希望有人可以指出我做错了的事情,以及已经尝试过的事情: 将Lucene版本从更新为 使用代替 特林的配置为或 这里的代码: 首先将在中生成索引,并 显示将成功查询该索引,然后希望删除该文档,但再次将证明删除操作失败。 这是pom依赖关系,以防有人可能需要测试 渴望得到答案。 问题答案: 您的问题出在分析仪中。将标记定