当前位置: 首页 > 知识库问答 >
问题:

TermQuery没有给出预期的结果作为QueryParser-Lucene 7.4.0

陆博易
2023-03-14

我正在使用Standard ardAnalyser索引10个文本文档。

public static void indexDoc(final IndexWriter writer, Path filePath, long timstamp)
    {
        try (InputStream iStream = Files.newInputStream(filePath))
        {
            Document doc = new Document();

            Field pathField = new StringField("path",filePath.toString(),Field.Store.YES);
            Field flagField = new TextField("ashish","i am stored",Field.Store.YES);
            LongPoint last_modi = new LongPoint("last_modified",timstamp);
            Field content = new TextField("content",new BufferedReader(new InputStreamReader(iStream,StandardCharsets.UTF_8)));

            doc.add(pathField);
            doc.add(last_modi);
            doc.add(content);
            doc.add(flagField);

            if(writer.getConfig().getOpenMode()==OpenMode.CREATE)
            {
                System.out.println("Adding "+filePath.toString());
                writer.addDocument(doc);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }



    } 

上面是用来索引文档的代码片段。出于测试目的,我正在搜索一个名为“灰烬”的字段。

当我使用QueryParser时,Lucene给出了预期的搜索结果。

public static void main(String[] args) throws Exception
    {
        String index = "E:\\Lucene\\Index";
        String field = "ashish";
        int hitsPerPage = 10;

        IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));
        IndexSearcher searcher = new IndexSearcher(reader);
        Analyzer analyzer = new StandardAnalyzer();

        QueryParser parser = new QueryParser(field, analyzer);

        String line = "i am stored";

        Query query = parser.parse(line);
      //  Query q = new TermQuery(new Term("ashish","i am stored"));
        System.out.println("Searching for: " + query.toString());



        TopDocs results = searcher.search(query, 5 * hitsPerPage);
        ScoreDoc[] hits = results.scoreDocs;

        int numTotalHits = Math.toIntExact(results.totalHits);
        System.out.println(numTotalHits + " total matching documents");

        for(int i=0;i<numTotalHits;i++)
        {
             Document doc = searcher.doc(hits[i].doc);
             String path = doc.get("path");
             String content = doc.get("ashish");
             System.out.println(path+"\n"+content);

        }



    } 

但是,当我使用TermQuery API时,我没有得到所需的结果。我正在展示我为TermQuery所做的代码更改。

public static void main(String[] args) throws Exception
    {
        String index = "E:\\Lucene\\Index";
        String field = "ashish";
        int hitsPerPage = 10;

        IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));
        IndexSearcher searcher = new IndexSearcher(reader);
        Analyzer analyzer = new StandardAnalyzer();

      //  QueryParser parser = new QueryParser(field, analyzer);

        String line = "i am stored";

       // Query query = parser.parse(line);
       Query q = new TermQuery(new Term("ashish","i am stored"));
        System.out.println("Searching for: " + q.toString());

        TopDocs results = searcher.search(q, 5 * hitsPerPage);
        ScoreDoc[] hits = results.scoreDocs;

        int numTotalHits = Math.toIntExact(results.totalHits);
        System.out.println(numTotalHits + " total matching documents");

        for(int i=0;i<numTotalHits;i++)
        {
             Document doc = searcher.doc(hits[i].doc);
             String path = doc.get("path");
             String content = doc.get("ashish");
             System.out.println(path+"\n"+content);
             System.out.println("----------------------------------------------------------------------------------");
        }



    }

对stackoverflow本身做了一些研究,例如Lucene TermQuery和QueryParser,但没有找到任何实用的解决方案,而且Lucene版本在这些例子中非常古老。

会感激你的帮助。

提前谢谢!

共有2个答案

孙昂然
2023-03-14

真正的问题是这里没有分析查询字符串。因此,在索引文档时使用相同的分析器,并尝试使用以下代码分析查询字符串,然后进行搜索。

IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));
IndexSearcher searcher = new IndexSearcher(reader);

QueryParser parser = new QueryParser("ashish", analyzer);
Query query = new TermQuery(new Term("ashish", "i am stored"));
query = parser.parse(query.toString());
ScoreDoc[] hits = searcher.search(query, 5).scoreDocs;
南宫海超
2023-03-14

我得到了我的问题的答案在这篇文章的链接,解释了如何TermQuery工作

TermQuery按原样搜索整个字符串。这种行为会给您带来不正确的结果,因为索引数据通常是标记化的。

在发布的代码中,我将整个搜索字符串传递给TermQuery,比如
Query q=new TermQuery(new Term(“ashish”,“我被存储”);
现在在上面的情况下,Lucene找到了“我被存储”,这是永远不会发生的
相反,我尝试像Query q=new TermQuery(new Term(ashish,存储))一样搜索;
上面的查询给了我一个预期的结果。

谢谢,阿什

 类似资料:
  • 这是我索引中的文档(也可以有几个): 从逻辑上讲,我试图建立这个条件: 我的问题(来自kibana): 我正在与上述范围内的字段的范围查询与上面的其他字段进行比较。但没有得到任何命中!我想检索具有在给定和日期。 在这个领域很缺乏经验,不知道为什么不起作用!请帮助如何修复此查询以做到这一点?

  • 我目前不确定Lucene中QueryParser与TermQuery的行为;我用的是Lucene3.6。 在我的示例中,我将在同一索引上尝试以下示例,其中所讨论的字段设置在和处。 在这两种情况下,和都无法再现与相同的语法;通过打印查询,我可以看到: Q1= Q2= Q3= 由于这种差异,查询和不返回任何结果,而查询返回预期的结果。 问题:有没有一种方法让查询解析器重现与TermQuery相同的查询

  • 我有一个索引,其中我的每个对象都有状态字段,该字段可以有一些预定义的值。我想获取所有状态为“已启动”、“已更新”、“已删除”的查询,任何与这些匹配的,因此我使用Querybuilder和nativeSearchQuery,通过ElasticsearchOperations在控制台上打印的java创建了这个查询: 我的索引中有“INITIATED”状态的数据,但没有得到查询中提到的任何状态的人。请如

  • 片段着色器 结果是一个绿色屏幕,里面有一个黑色矩形。但我希望长方形改为蓝色。我的代码有问题吗?

  • 我相信下面的代码 应打印 事实上,当Python正常执行时就是这种情况(这里是在Wandbox上运行的示例)。 但现实是无情的(像往常一样);Google Colborator打印一个没有“三个点”的结果: 我还用本地安装的Jupyter(Python 3.7.13、Jupyter notebook 6.4.12、IPython 7.34.0)尝试了相同的代码,结果与Google Colabora