Lucene 6.2.1如何在不知道其名称的情况下获取所有字段名称或在所有字段中进行搜索

时间:2018-07-04 09:34:06

标签: java lucene

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

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

    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)

         

    最终AtomicReader reader = searcher.getAtomicReader();

         

    最终FieldInfos infos = reader.getFieldInfos(); (v。4.2.1)

  2. ...还是有一种方法(不一定是MultiFieldQueryParser)提供了对所有字段的搜索而没有其名称(6.2.1版)?

2 个答案:

答案 0 :(得分:0)

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

在这种情况下,最好的方法是根据Elasticsearch或solr如何处理此问题的结构来实现普通的全文本搜索:

  • 向每个文档添加专用的“全文” TextField(TextField用于全文搜索)
  • 用其他字段的所有信息填充全文字段,并用空格隔开
  • 根据全文f搜索您的字词

这是可以轻松实现全文搜索的方式。无需知道字段名称并对其进行迭代。

答案 1 :(得分:0)

如果您已经实施了将希望搜索的所有文本放入一个通用字段的解决方案,那么为什么要更改它。如果您想更改它(因为它看起来像是黑客),请让我向您保证,这是此问题的<正确>最佳解决方案。 SolrElasticSearch的文档中都建议使用这种模式。

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


如果您是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或类似物中的字段名称的列表。