Java lucene中的Regexpquery不工作

Java lucene中的Regexpquery不工作,java,lucene,Java,Lucene,我正在使用lucene 5.4使用regex搜索文件中的一些文本,但是regexpquery不起作用,尽管phrasequery和普通查询都起作用,并且能够找到带有搜索字符串的文件,但是当我运行regex查询时,Lucence找不到任何包含该regex的文件 索引创建代码: public IndexWriter generateIndex(String docsPath) throws IOException { String indexPath = System.getPrope

我正在使用lucene 5.4使用regex搜索文件中的一些文本,但是regexpquery不起作用,尽管phrasequery和普通查询都起作用,并且能够找到带有搜索字符串的文件,但是当我运行regex查询时,Lucence找不到任何包含该regex的文件

索引创建代码:

public IndexWriter generateIndex(String docsPath) throws IOException {

      String indexPath = System.getProperty("java.io.tmpdir") +File.separator+"indexDirectory";
        if (indexPath == null) {
          throw new IOException("System property 'java.io.tmpdir' does not specify a tmp dir");
        }
        File tmpDir = new File(indexPath);
        if (!tmpDir.exists()) {
          boolean created = tmpDir.mkdirs();
          if (!created) {
            throw new IOException("Unable to create tmp dir " + tmpDir);
          }
        }

    boolean create = true;
    final Path docDir = Paths.get(docsPath);
    if (!Files.isReadable(docDir)) {
        System.out.println("Document directory '" + docDir.toAbsolutePath()
                + "' does not exist or is not readable, please check the path");
        System.exit(1);
    }

    Date start = new Date();
    try {
        System.out.println("Indexing to directory '" + indexPath + "'...");

        Directory dir = FSDirectory.open(Paths.get(indexPath));
        Analyzer analyzer = new StandardAnalyzer();
        IndexWriterConfig iwc = new IndexWriterConfig(analyzer);

        if (create) {
            iwc.setOpenMode(OpenMode.CREATE);
        } else {
            iwc.setOpenMode(OpenMode.CREATE_OR_APPEND);
        }

        IndexWriter writer = new IndexWriter(dir, iwc);
        indexDocs(writer, docDir);
        setIndexWriter(writer);

        Date end = new Date();
        System.out.println(end.getTime() - start.getTime() + " total milliseconds");
        writer.close();
    } catch (IOException e) {
        System.out.println(" caught a " + e.getClass() + "\n with message: " + e.getMessage());
    }

    return getIndexWriter();
}

static void indexDocs(final IndexWriter writer, Path path) throws IOException {
    if (Files.isDirectory(path)) {
        Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                try {
                    indexDoc(writer, file, attrs.lastModifiedTime().toMillis());
                } catch (IOException ignore) {
                    // don't index files that can't be read.
                }
                return FileVisitResult.CONTINUE;
            }
        });
    } else {
        indexDoc(writer, path, Files.getLastModifiedTime(path).toMillis());
    }
}
static void indexDoc(IndexWriter writer, Path file, long lastModified) throws IOException {
    try (InputStream stream = Files.newInputStream(file)) {
        Document doc = new Document();
        Field pathField = new StringField("path", file.toString(), Field.Store.YES);
        doc.add(pathField);

        doc.add(new LongField("modified", lastModified, Field.Store.NO));
        doc.add(new TextField("contents",
                new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))));

        if (writer.getConfig().getOpenMode() == OpenMode.CREATE) {
            System.out.println("adding " + file);
            writer.addDocument(doc);
        } else {
            System.out.println("updating " + file);
            writer.updateDocument(new Term("path", file.toString()), doc);
        }
    }
}
正在运行的查询解析器代码:

QueryParser parser = new QueryParser(field, analyzer);
Query query = parser.parse("+program-id");
我们将搜索的源代码:

IDENTIFICATION DIVISION.
   PROGRAM-ID.  ACINSTAL.

   ENVIRONMENT DIVISION.

   DATA DIVISION.
   WORKING-STORAGE SECTION.

请提供帮助。

如注释中所述,正则表达式查询必须与单个令牌匹配。没有一种查询类型允许您拥有一个跨多个术语的正则表达式。在我看来,通常应该避免对全文内容进行正则表达式查询(如果字段是一个简单的标识符,或者类似的,那就不同了)。如果您正在使用它们,这可能表明您未能提供有效的全文搜索。如果可用,您应该倾向于使用更典型的全文搜索工具,例如通配符、模糊、邻近和范围查询,或者调整分析以提供更有用的搜索结果

但是,如果您坚持这样做,有两种方法可以支持这种搜索

  • 您可以通过支持搜索需求的方式将分析更改为标记化。使用
    StringField
    将创建一个令牌,因此正则表达式查询将比您预期的更有效。当然,这会导致性能下降,并且对更标准的查询样式的支持会差得多。如果字段是某种类型的字符串标识符,这可能是最好的解决方案。如果您希望对全文字段提供强大的全文搜索支持,那么这几乎肯定是一个糟糕的解决方案

  • 您可以使用更适合这种情况的查询。在您提供的示例中,一个简单的短语查询可以很好地完成这项工作,正如您自己所指出的,因此很难说出您在这里需要什么。通常,对于跨越多个术语的复杂正则表达式查询,您必须使用API来支持它,通常是使用多个术语组合来支持它

    另外,值得注意的是,还提供了,它设计用于使用
    SpanQuery
    api。它不支持正则表达式,但如果将通配符查询组合成带有扳手的短语最终成为您所需要的,那么QueryParser可能是一个方便的工具


  • “不工作”到底意味着什么?它会引发异常吗?异常消息是什么?它是否会产生错误/意外的结果?它产生了什么结果?预期的结果是什么?如果您根据编辑问题,则更有可能获得帮助。您的RegexpQuery允许空白。您的代码不包含IndexWriterConfig(或示例文件)。请注意,solr查询与反向索引中生成的标记相匹配。通常,此标记中没有空格。@Karstener。我已经更新了完整的源代码和示例文件代码,我将在其中进行搜索。请仔细查看。StandardAnalyzer不仅会删除空白,还会删除点。RegexprQuery不使用分析器:您尝试查找标记“program-id”。但只有“program-id.”-->否hit@KarstenR. “enviro.*division”这个正则表达式既没有空格也没有点,但它也不起作用
    IDENTIFICATION DIVISION.
       PROGRAM-ID.  ACINSTAL.
    
       ENVIRONMENT DIVISION.
    
       DATA DIVISION.
       WORKING-STORAGE SECTION.