Java Lucene同时搜索存储字段和未存储字段

Java Lucene同时搜索存储字段和未存储字段,java,lucene,Java,Lucene,我正在使用Lucene 7.4,并为txt文件的示例编制了索引。 我已经存储了一些字段,例如路径和文件名, 以及一个内容字段,该字段在将文档传递给IndexWriter之前未存储。 因此,“我的内容”字段包含文件的已处理(例如标记化、词干化)内容数据,“我的文件名”字段包含未处理的文件名和整个字符串 try (InputStream stream = Files.newInputStream(file)) { // create empty document

我正在使用Lucene 7.4,并为txt文件的示例编制了索引。 我已经存储了一些字段,例如路径和文件名, 以及一个内容字段,该字段在将文档传递给IndexWriter之前未存储。 因此,“我的内容”字段包含文件的已处理(例如标记化、词干化)内容数据,“我的文件名”字段包含未处理的文件名和整个字符串

try (InputStream stream = Files.newInputStream(file)) {

            // create empty document
            Document doc = new Document();

            // add the last modification time field
            Field lastModField = new StoredField(LuceneConstants.LAST_MODIFICATION_TIME, Files.getAttribute(file, "lastModifiedTime", LinkOption.NOFOLLOW_LINKS).toString());
            doc.add(lastModField);
            
            // add the path Field
            Field pathField = new StringField(LuceneConstants.FILE_PATH, file.toString(), Field.Store.YES);
            doc.add(pathField);

            // add the name Field
            doc.add(new StringField(LuceneConstants.FILE_NAME, file.getFileName().toString(), Field.Store.YES));

            // add the content
            doc.add(new TextField(LuceneConstants.CONTENTS, new BufferedReader(new InputStreamReader(stream))));

            System.out.println("adding " + file);
            writer.addDocument(doc);

现在,据我所知,我必须使用2个QueryParser,因为我需要使用2个不同的分析器来搜索两个字段,每个字段一个。 我不知道如何把它们结合起来。 我想要的是一个TopDoc,其中的结果是按相关性得分排序的,即通过文件名字段搜索和内容字段搜索得到的2个相关性得分的组合。 Lucene 7.4是否为您提供了解决此问题的简单方法

附:这是我很长时间以来的第一篇帖子,如果不是的话。请注意任何格式或内容问题

编辑: 用于索引内容字段和搜索内容字段的分析器:

Analyzer myTxtAnalyzer = CustomAnalyzer.builder()
                    .withTokenizer("standard")
                    .addTokenFilter("lowercase")
                    .addTokenFilter("stop")
                    .addTokenFilter("porterstem")
                    .build();
我使用KeywordAnalyzer搜索文件名字段,重申一下,它是存储的,所以没有分析

我的程序应该为文件编制索引,并在该索引上搜索,检索 最相关文件的列表。如果搜索字符串(可能包含空格)与文件名完全匹配, 我希望这会严重影响我的搜索结果

我是一名计算机科学专业的学生,这是我和Lucene的第一个项目。 如果没有可用的功能,一切都很好。我所要求的不是我任务的要求。我只是在思考,我觉得这可能已经有了一个简单的解决方案。但我似乎找不到它,如果它存在的话

编辑2: 我有一个误解,但是当使用存储时会发生什么。是/。否。 我的问题与此无关。 字符串没有标记,因为它位于StringField中。 我猜是因为它被储存起来了。 然而,我的问题仍然存在。
有没有一种方法可以同时搜索标记化字段和非标记化字段?

正如@andrewjames提到的,您不需要在示例中使用多个分析器,因为只有
TextField
得到分析,而
StringField
没有得到分析。如果您确实需要为不同的字段使用不同的分析器,Lucene可以适应这种情况。为此,您可以使用
perfieldanalyzerrapper
,它基本上让您指定一个默认的分析器,然后指定任意多个字段特定的分析器(作为字典传递给
perfieldanalyzerrapper
)。然后,在分析文档时,如果指定了字段特定的分析器,它将使用该分析器;如果未指定,它将使用您为
perfiedanalyzerrapper
指定的默认分析器

无论是使用单个分析器还是通过
perfieldanalyzerrapper
使用多个分析器,您只需要一个
QueryParser
,您将通过一个分析器或封装多个分析器的
perfieldanalyzerrapper
传递该分析器

有些字段已存储,有些字段未存储,这一事实对搜索这些字段没有影响。对搜索来说唯一重要的是字段被索引,并且
StringField
s和
TextField
s始终被索引

你提到了以下几点:

我使用KeywordAnalyzer搜索文件名字段,重申一下,它是存储的,所以没有分析

字段是否被存储与是否被分析无关。对于文件名字段,您的代码使用了
StringField
field.Store.YES
。因为它是一个
StringField
,所以它将被索引,但不会被分析,而且因为您指定存储字段,所以它将被存储。因此,由于未分析字段,因此不会使用
关键字分析器
或任何其他分析器:-)

有没有一种方法可以同时搜索标记化字段和非标记化字段

这里真正的问题不是同时搜索标记化和非标记化字段,而是同时搜索多个字段。一个是标记化的,一个不是标记化的,这一事实对lucene来说并不重要。要一次搜索多个字段,可以使用
布尔查询
,使用此查询对象,可以向其中添加多个查询,每个字段一个查询,并指定子查询之间的
ie
必须
ie
应该
关系


我希望这有助于为您澄清问题。

您能否澄清为什么需要两种不同的分析仪?通常,只有当您对不同字段有不同的标记化/过滤需求时,才会出现这种情况。但是使用这些不同的字段类型(
StringField
TextField
)并不强制您这样做,因为
StringField
是按原样索引的-标记化被跳过。也许如果你的问题显示了你当前需要使用的分析器和查询解析器,问题就会更清楚。