【问题标题】:Lucene 6.2.1 How to get all field names or search across all fields without knowing their namesLucene 6.2.1 如何在不知道其名称的情况下获取所有字段名称或搜索所有字段
【发布时间】:2018-07-04 09:34:05
【问题描述】:

我是 Lucene 的新手,我想知道是否有一种方法可以在不知道其名称的情况下搜索多个文档中的所有可能字段,或者...另一种方法:获取所有字段名称(版本 6.2.1 )

  1. 例如:如何从 'fields' 数组中获取所有名称,而不是像下面的示例那样填充它们

    Analyzer analyzer = new StandardAnalyzer();
    String querystr = "test";
    String[] fields = {"title","isbn","desc", "name", "surname", "description"};
    BooleanClause.Occur[] flags = new BooleanClause.Occur[fields.length];
    Arrays.fill(flags, BooleanClause.Occur.SHOULD);
    Query query = MultiFieldQueryParser.parse(querystr, fields, flags, analyzer);
    

    我已经检查了这些主题:

    a)How to search across all the fields?

    我们已经实现了这个答案:

    1) 索引时间方法:使用包罗万象的字段。这只不过是附加所有字段中的所有文本(输入文档中的总文本)并将产生的巨大文本放在单个字段中。您必须在索引时添加一个附加字段以充当一个包罗万象的字段。

    但如果有可能我们想改变它

    b)https://www.programcreek.com/java-api-examples/index.php?api=org.apache.lucene.queryParser.MultiFieldQueryParser

    c)IndexReader.getFieldNames Lucene 4

    但这些解决方案在 Lucene 版本 6.2.1 中不存在

    IndexReader.getFieldNames() (v. 3.3.0)

    final AtomicReader reader = searcher.getAtomicReader();

    最终的 FieldInfos 信息 = reader.getFieldInfos(); (v. 4.2.1)

  2. ...或者是否有一种方法(不一定是 MultiFieldQueryParser)可以搜索所有没有名称的字段(v. 6.2.1)?

【问题讨论】:

  • 据我了解,您想在文档中的所有字段上添加一种全文搜索?

标签: java lucene


【解决方案1】:

如果您已经实施了将要搜索的所有文本放入一个包罗万象的字段的解决方案,为什么要更改它。如果您想更改它,因为它看起来像 hack,让我向您保证,这是解决此问题的正确、最佳的解决方案。这是SolrElasticSearch 的文档中推荐的模式。

生成一个字段列表并针对所有字段创建一个大而复杂的查询是 hack。您绝对应该坚持使用您已经实施的解决方案。


如果您是 poor, unfortunate souls 中的一员,无法重新索引以添加包含您需要搜索的所有内容的新字段,并且您确实需要一种方法来获取所有字段的列表并针对它们进行查询, 干得好。您可以简单地获取 LeafReader 中的字段列表,并且 DirectoryReader(来自 DirectoryReader.open,例如)包含 LeafReaderContexts 列表。因此,遍历 LeafReaders,并获取并合并每个字段的列表,以获得索引中字段的完整列表:

DirectoryReader reader = DirectoryReader.open(Paths.get('/path/to/my/index'));
HashSet<String> fieldnames = new HashSet<String>();
for (LeafReaderContext subReader : reader.leaves) {
    Fields fields = subReader.reader().fields();
    for (String fieldname : fields) {
        fieldnames.add(fieldname);
    }
}

您可以在应用程序启动或重新打开阅读器时执行此操作,而不是每次查询时执行此操作。现在您有了可以传递给MultiFieldQueryParser 的字段名称列表,或者将一堆 TermQueries 放入 BooleanQuery 或 DisjunctionMaxQuery 等。

【讨论】:

  • 感谢您的解释 :) 就像我说的我是 Lucene 新手,所以很高兴知道我们的方法是正确的。
【解决方案2】:

根据您的问题,我建议您只是想搜索一些术语以及实际索引这些值的字段,知道这些不是很重要吗?

在这种情况下,最好的方法是根据 elasticsearch 或 solr 处理此问题的结构来实现正常的全文搜索:

  • 为每个文档添加一个专用的“全文”TextField(TextField 用于全文搜索)
  • 用其他字段的所有信息填充全文字段,用空格分隔
  • 根据您的全文 f 使用您的术语进行搜索

这就是如何以简单的方式实现全文搜索。无需知道字段名称并对其进行迭代。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多