java - Lucene 中跨文档共享的标记和属性

标签 java lucene

我的应用程序需要保留文件索引,其中的文件通过标签和属性识别,建议使用 Lucene (Java) 文档架构,例如:

tags: i s (indexed, stored)
attributes: i s
content: i
fileId: i s 

(实际文件是通过 sqlite 中的 id 查找的。)但是,虽然一个文件只有一组标签/属性,但它可能有多个版本的内容(每个版本都由一个 versionId 标识)。

唯一真正的解决方案似乎是一种文档类型,每个版本一个文档,这样标签和属性在许多文档中都是冗余的:

tags: i s
attributes: i s
content: i
versionId: i s
fileId: i s

我对这个模式的担心是它是否足够高效和足够紧凑。所以这是我的问题:

  1. 如果我正确理解了 Lucene 的索引方案,当相同的长字符串在许多文档中被索引为一个字段时,与仅索引一次相比,这并没有真正增加索引。正确吗?

  2. 如果我创建单个 Term 对象,将其存储,然后将其添加到多个文档中,索引中的每个文档的完整字符串数据是否会重复?如果是这种情况,我是否最好将标签/属性的实际存储放入 sql 中?

  3. 据我所知,查询结果中返回的唯一信息是按分数排序的文档本身。要确定哪些字段满足匹配文档的查询,我必须对每个文档的字段进行单独查询,还是什么?

了解这只是一个客户端应用程序,因此并发访问不是问题,并且索引更新将很少见(每次用户重新标记或编辑/创建文件时)。我主要关心单个用户的实时响应,并在某种程度上关心索引大小(尽管更多的是为了节省内存而不是磁盘空间)。


更多背景

我考虑过一些替代文档架构,但拒绝了它们。我最初的直觉是通过将文档分为两种类型来避免数据重复,一种类型代表一个文件:

tags: i s
attributes: i s
fileId: i s

...但是还有一种文档类型用于表示文件的版本:

content: i
fileId: i s
versionId: i s

这有很多问题:

首先,它需要对内容和标签/属性进行单独查询,然后将内容结果与文件进行匹配:对于结果中的每个版本文档,我必须查看其 fileId,然后在单独的查询中查找相应的文件文档。虽然这是一种标准的关系技术,但我的理解是,在 Lucene 中这是一件相当笨拙和缓慢的事情。

其次,对于同时需要“披萨”和“热狗”的查询,我想取回在标签/属性或内容或“热狗”中包含这两个术语的文件版本另一个是“披萨”。通过将标签/属性从它们的内容中分离出来,这变得非常棘手(而且可能很昂贵)。

所以也许我可以通过保留多个内容字段来将内容和标签/属性放在一起:

tags: i s
attributes: i s
content: i  (multiple fields)
fileId: i s 

问题是我是否可以识别一个内容字段,以便我可以知道哪个版本的内容产生了命中。我可以根据版本 ID 以不同方式命名每个内容字段:

tags: i s
attributes: i s
content {versionId}: i
content {versionId}: i
content {versionId}: i   # etc.
fileId: i s

即使我可以识别导致文档与查询匹配的内容字段,合并版本也会打乱评分。

最佳答案

  1. If I understand Lucene's indexing scheme correctly, when the same long string is indexed as a field in many documents, this doesn't really bulk out the index compared to if it were indexed just once. Correct?
  2. If I create a single Term object, make it stored, and then add it to many documents, does the full string data get duplicated for each document in the index? If this is the case, am I just best off putting the actual storage of the tags/attributes into sql?
  3. As far as I can tell, the only info that comes back in query results is the documents themselves ordered by score. To determine which fields satisfied the query for a matched document, must I do separate queries on the fields for each document, or what?
  1. 正确。 Lucene 存储了一个将字符串映射到数字标识符的字典,因此消耗的内存只是多次存储标识符。
  2. 我认为将标签和属性存储在 Lucene 中是安全的。
  3. 您不需要单独的查询 - 一旦您拥有一个 Document 对象,您就可以使用例如getField()获取相关字段信息。 由于您关注 Lucene 性能,建议您阅读 Scaling Lucene and Solr ,其中涵盖了许多性能技巧。

关于java - Lucene 中跨文档共享的标记和属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/743119/

相关文章:

java.lang.LinkageError : Package versions: jackson-core=2. 13.3、 jackson -databind=2.13.3、 jackson -dataformat-xml=2.13.3、 jackson -datatype-jsr310=2.13.3

java - 无法理解和解决此程序的方法覆盖错误

search - Solr 不会搜索属于嵌套实体的字段

java - QueryDSL 和 Hibernate 搜索 isNull 和 isNotNull 查询

zend-framework - Symfony Zend Lucene 搜索多个表

java - PDF框2.0 : Get color information in TextStripper

java - 仅当满足特定 boolean 情况时才让 Observable 返回

java - 在服务器端表单提交处理程序中检查引用是一个好习惯吗?

elasticsearch - ElasticSearch:是否可以通过在ElasticSearch中简单地提供查询来搜索文档中的所有文件

java - 从 CQ5.5 索引中获取搜索词建议