在lucene中存储非索引二进制数据

时间:2015-12-16 23:40:39

标签: lucene

如何将非索引字节数组存储到lucene文档中?

我试过这些:

     doc.add(new Field("bin1", new InputStreamReader(new ByteArrayInputStream(new byte [100000]))));
     doc.add(new BinaryDocValuesField("bin2", new BytesRef(new byte [100000])));

并且没有任何效果(字段未存储,查询时无法检索)

测试代码:

  String index="dms1";

  Directory indexDirectory = FSDirectory.open(Paths.get(index));
  StandardAnalyzer analyzer = new StandardAnalyzer();
     IndexWriterConfig iwc = new IndexWriterConfig(analyzer);
     iwc.setOpenMode(IndexWriterConfig.OpenMode
             .CREATE
     );
     //create the indexer
  IndexWriter iw = new IndexWriter(indexDirectory, iwc);

  {
     Document doc = new Document();

     doc.add(new TextField("id", "1", Field.Store.YES));
     doc.add(new Field("bin1", new InputStreamReader(new ByteArrayInputStream(new byte [100000]))));
     doc.add(new BinaryDocValuesField("bin2", new BytesRef(new byte [100000])));

     iw.addDocument(doc);
     iw.commit();
  }

  DirectoryReader ir = DirectoryReader.open(indexDirectory);

  IndexSearcher is = new IndexSearcher(ir);


  QueryParser qp = new QueryParser(
          "",
          analyzer);
  Query q = qp.parse(
          //"content1:hp"
          "*:*"
  );
  TopDocs hits = is.search(q, 10);

  for (ScoreDoc scoreDoc : hits.scoreDocs) {
     Document doc = is.doc(scoreDoc.doc);

     System.out.println(doc);

     System.out.println("doc.getBinaryValue(bin1):" + doc.getBinaryValue("bin1"));;
     System.out.println("doc.getBinaryValues(bin1):" + doc.getBinaryValues("bin1"));;
     System.out.println("doc.getBinaryValues(bin1).length:" + doc.getBinaryValues("bin1").length);;
     System.out.println("doc.get(bin1):" + doc.get("bin1"));;

     System.out.println("doc.getBinaryValue(bin2):" + doc.getBinaryValue("bin2"));;
     System.out.println("doc.getBinaryValues(bin2):" + doc.getBinaryValues("bin2"));;
     System.out.println("doc.getBinaryValues(bin2).length:" + doc.getBinaryValues("bin2").length);;
     System.out.println("doc.get(bin2):" + doc.get("bin2"));;
  }

输出:

    Document<stored,indexed,tokenized<id:1>>
    doc.getBinaryValue(bin1):null
    doc.getBinaryValues(bin1):[Lorg.apache.lucene.util.BytesRef;@899e53
    doc.getBinaryValues(bin1).length:0
    doc.get(bin1):null
    doc.getBinaryValue(bin2):null
    doc.getBinaryValues(bin2):[Lorg.apache.lucene.util.BytesRef;@f98160
    doc.getBinaryValues(bin2).length:0
    doc.get(bin2):null

是否有人可以了解如何存储字节以及如何再次检索值?

我知道使用base64或其他编码的其他解决方案将字节转换为文本或将其存储为文件链接,但我需要知道的是更有效的方法,因为lucene API具有“二进制”方法所以我认为这应该是正确的方法。

lucene版本:5.3.1

1 个答案:

答案 0 :(得分:3)

使用StoredField。您可以将BytesRef或字节数组本身传入字段:

byte[] myByteArray = new byte[100000];
document.add(new StoredField("bin1", myByteArray));

就检索价值而言,您已经在正确的轨道上。类似的东西:

Document resultDoc = searcher.doc(docno);
BytesRef bin1ref = resultDoc.getBinaryValue("bin1");
bytes[] bin1bytes = bin1ref.bytes;

顺便说一下,您尝试过两个字段的问题:

  • bin1:当您将读者传递给Field构造函数时,它决定将其视为TextField,它将被编入索引而不会存储,实际上与您正在查找的内容相反对于。无论如何,该构造函数已被弃用,仅支持使用TextField

    如果您选择赞成只传递byte[]而不是Reader,那么它实际上会起作用,因为它会起到StoredField的作用(如上所示) ,虽然该构造函数也已弃用)。

  • bin2:DocValuesFields的工作方式不同。如果您好奇,可以read up a bit on that here