【问题标题】:Phrase query in Lucene 6.2.0Lucene 6.2.0 中的短语查询
【发布时间】:2017-01-11 12:05:15
【问题描述】:

我有这样的文件:

{ 
    "_id" : ObjectId("586b723b4b9a835db416fa26"), 
    "name" : "test", 
    "countries" : {
        "country" : [
            {
                "name" : "russia iraq"
            }, 
            {
                "name" : "USA china"
            }
        ]
    }
}

在 MongoDB 中,我尝试使用短语查询(Lucene 6.2.0)来检索它。我的代码如下所示:

StandardAnalyzer analyzer = new StandardAnalyzer();         

         // 1. create the index
            Directory index = new RAMDirectory();
            IndexWriterConfig config = new IndexWriterConfig(analyzer); 
            try {       

                 IndexWriter w = new IndexWriter(index, config);                    
                MongoClient client = new MongoClient("localhost", 27017);
                DB database = client.getDB("test123");
                DBCollection coll =  database.getCollection("test1");
                //MongoCollection<org.bson.Document> collection = database.getCollection("test1");
            DBCursor cursor = coll.find();                  
                    System.out.println(cursor);
                 while (cursor.hasNext()) { 
                     BasicDBObject obj = (BasicDBObject) cursor.next();

                      Document doc = new Document();
                BasicDBObject f = (BasicDBObject) (obj.get("countries"));
                                List<BasicDBObject> dts = (List<BasicDBObject>)(f.get("country"));   
                     doc.add(new TextField("id",obj.get("_id").toString().toLowerCase(), Field.Store.YES));
                     doc.add(new StringField("name",obj.get("name").toString(), Field.Store.YES));  
                   doc.add(new StringField("countries",f.toString(), Field.Store.YES));

                   for(BasicDBObject d : dts){
                      doc.add(new StringField("country",d.get("name").toString(), Field.Store.YES));
    //               
               }
                    w.addDocument(doc);                    

                 }
                 w.close();

我的搜索结果如下:

 PhraseQuery query = new PhraseQuery("country", "iraq russia" );


                   // 3. search
                   int hitsPerPage = 10;
                   IndexReader reader = DirectoryReader.open(index);

                   IndexSearcher searcher = new IndexSearcher(reader);
                   TopDocs docs = searcher.search(query, hitsPerPage);
                   ScoreDoc[] hits = docs.scoreDocs;

                  //  4. display results
                   System.out.println("Found " + hits.length + " hits.");
                   for(int j=0;j<hits.length;++j) {
                       int docId = hits[j].doc;
                       Document d = searcher.doc(docId);
                       System.out.println(d);
                   }


                   reader.close();
    }
    catch (Exception e) {
            e.printStackTrace();
        } 

此查询的命中率为零。谁能告诉我做错了什么? 使用的罐子: lucene-queries4.2.0 lucene-queryparser-6.2.1 lucene-analyzers-common-6.2.0

【问题讨论】:

  • 因为我没有 mongodb,所以我无法重现它,你能显示 d.get("name").toString() 中传递的内容吗?
  • 这是我最终文档的样子: Document stored,indexed,omitNorms,indexOptions=DOCS stored,indexed,omitNorms,indexOptions =DOCS 存储、索引、标记 存储、索引、代币化>

标签: mongodb lucene


【解决方案1】:

我做了一些改变,比如:

Query query = new PhraseQuery.Builder()
                        .add(new Term("country", "iraq"))
                        .add(new Term("country", "russia"))
                        .setSlop(2)
                        .build();

而且我在索引时更改了字段的类型:

for(BasicDBObject d : dts){
                  doc.add(newTextField("country",d.get("name").toString(), Field.Store.YES));

           }

但是谁能告诉我在索引时 StringFeild 和 TextFeild 之间的区别?

【讨论】:

【解决方案2】:

首先,切勿混合 Lucene 版本。你所有的罐子应该是相同的版本。将 lucene 查询升级到 6.2.1。在实践中,您可能会也可能不会遇到混淆 6.2.0 和 6.2.1 的问题,但您绝对应该升级 lucene-analyzers-common。


PhraseQuery 不会为您分析,您必须单独添加术语。在您的示例中,“iraq russia”被视为单个术语,而不是两个单独的(分析的)术语。

它应该看起来像这样:

Query query = new PhraseQuery.Builder()
    .add(new Term("country", "iraq"))
    .add(new Term("country", "russia"))
    .build();

如果你想要为你分析的东西,你可以使用 QueryParser:

QueryParser parser = new QueryParser("country", new StandardAnalyzer())
Query query = queryparser.parse("\"iraq russia\"");

【讨论】:

  • 感谢您的回复,我确实升级了我的 jar,但它似乎仍然无法正常工作。使用您发送的上述查询,我​​仍然得到 0 次点击
  • 当我尝试打印查询时,它会变成:国家:“伊拉克俄罗斯”
猜你喜欢
  • 2015-01-19
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
  • 2017-06-12
  • 1970-01-01
相关资源
最近更新 更多