`
baobeituping
  • 浏览: 1042175 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Lucene3 查询索引

阅读更多

package lucene3;

import java.io.File;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class DBQuery {

 /**
  * @param args
  */
 public static void main(String[] args) {
  try {
   Directory dir = FSDirectory.open(new File("d://lucene3"));
   IndexSearcher searcher = new IndexSearcher(dir, true);
   Query q = new TermQuery(new Term("ID", "2"));
   TopDocs hits = searcher.search(q, 10);
   ScoreDoc[] docs = hits.scoreDocs;
   for(int i=0;i<docs.length;i++)
   {
    Document doc = searcher.doc(docs[i].doc);
    System.out.println("ID:"+doc.get("ID")+",Name:"+doc.get("Name"));
   }
   searcher.close();
  } catch (Exception e) {
   e.printStackTrace();
  } 

 }

}

 

注释:

使用索引进行查询的主要步骤:

1、打开已有的索引,创建IndexSearcher对象

2、指定查询用到的Field和查询字符串,创建TermQuery

3、使用IndexSearcher进行查询,查询结果以TopDocs对象返回。在这里search方法的第二个参数指定返回前N个记录。

 

主要对象说明:

1、Term

     Term是查询使用的基本单位,对应与在索引中使用的Field类。可以将其理解为一个map,其中key为索引中Field name,value为查询字符串。

     当查询字符串为一个单词的情况下,不会有任何问题;但是当需要查询查询字符串为多个单词或是一句话的时候就会查不出来。这个主要原因是,在建立索引时我们对Field中的内容进行了分词,但在查询时,对查询字符串没有做分词,整个做为一个单词处理,当然查不到了。

     要解决这个问题,针对上面的例子,只需要去掉new TermQuery这句,换成下面的代码:

Java代码 复制代码

public static void main(String[] args) {
  try {
   Directory dir = FSDirectory.open(new File("d://lucene3"));
   IndexSearcher searcher = new IndexSearcher(dir, true);
   //Query q = new TermQuery(new Term("ID", "2"));
   Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);  
   QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "ID", analyzer);
   Query q = parser.parse("2");
   TopDocs hits = searcher.search(q, 10);
   ScoreDoc[] docs = hits.scoreDocs;
   for(int i=0;i<docs.length;i++)
   {
    Document doc = searcher.doc(docs[i].doc);
    System.out.println("ID:"+doc.get("ID")+",Name:"+doc.get("Name"));
   }
   searcher.close();
  } catch (Exception e) {
   e.printStackTrace();
  } 
 }

     这里需要保证使用的analyzer与建立索引时用的一样即可。new QueryParser的第二个参数就是查询的FIELD。

     然后通过Query q = parser.parse("2");来解析要查询的内容。

     我们用query.toString()可以看到转化后的Term内容。

  • 当查询字符串="2"时,query.toString()=ID:2(前面为field name,后面为查询内容)
  • 当查询字符串="java and system"时,query.toString()=contents:java contents:system。可见已经被做了分词,同时去掉了连接字and

 

2、TopDocs

     此类封装了返回的符合条件的记录,其中:

  • totalHits为符合条件的记录总数;
  • scoreDocs为符合条件记录的数组,不过里面只记录了Document的ID。Document的实际内容,需通过IndexSearcher取docID对应的Document才能得到。

     需要注意-若设置在search方法中设置了返回记录数为N,则scoreDocs最多只会包含前N个文档;但是totalHits会返回匹配的总数量(类似google中显示的匹配的总页面数量)。scoreDocs.length可能不等于totalHits,做scoreDocs遍历时,直接用totalHits做为数组大小用的,容易引起bug!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics