View Javadoc

1   package org.musicontroller.core.searching;
2   
3   import java.io.IOException;
4   import java.util.LinkedList;
5   import java.util.List;
6   
7   import org.apache.log4j.Logger;
8   import org.apache.lucene.analysis.standard.StandardAnalyzer;
9   import org.apache.lucene.document.Document;
10  import org.apache.lucene.document.Field;
11  import org.apache.lucene.index.IndexReader;
12  import org.apache.lucene.queryParser.MultiFieldQueryParser;
13  import org.apache.lucene.queryParser.ParseException;
14  import org.apache.lucene.search.Hits;
15  import org.apache.lucene.search.IndexSearcher;
16  import org.apache.lucene.search.Query;
17  import org.apache.lucene.search.Searcher;
18  import org.apache.lucene.search.Sort;
19  import org.apache.lucene.search.SortField;
20  import org.musicontroller.service.FileUtils;
21  
22  /**
23   * The Searcher is an object that is used for querying the Lucene-index
24   * that is maintained by the Indexer.
25   * 
26   * @author arjanverstoep
27   * @version $Id: MCSearcher.java,v 1.1 2010/03/16 18:55:42 varienaja Exp $
28   * @see Indexer
29   * 
30   */
31  public class MCSearcher implements ISearcher {
32  	private static final Logger log = Logger.getLogger(MCSearcher.class);
33  
34  	public List<String> searchTopSongsForKeyword(String username, String keyword) {
35  		List<String> result = new LinkedList<String>();
36  		try {
37  			IndexReader reader = IndexReader.open(FileUtils.getIndexdir());
38  		    Searcher searcher = new IndexSearcher(reader);
39  		    
40  		    Query query = MultiFieldQueryParser.parse(new String[]{username,keyword,"song"},new String[]{"user","keyword","type"},new StandardAnalyzer());
41  		    Hits hits = searcher.search(query,new Sort(new SortField[]{SortField.FIELD_SCORE,new SortField("user_"+username,SortField.INT,true)}));
42  		    int counter=0;
43  		    while (counter<hits.length() && counter<25) {
44  		    	Document doc = hits.doc(counter);
45  		    	System.out.print(hits.score(counter));
46  			    System.out.println(doc);
47  		    	Field song = doc.getField("song");
48  		    	Field band = doc.getField("band");
49  		    	String s = song==null ? "" : song.stringValue(); 
50  		    	s = s + (band==null ? "" : band.stringValue());
51  		    	s = s + hits.score(counter);
52  		    	result.add(s);
53  		    	counter++;
54  		    }
55  		    reader.close();
56  		} catch (IOException e) {
57  		} catch (ParseException e) {
58  		}
59  	    return result;
60  	}
61  
62  	/*
63  	 * (non-Javadoc)
64  	 * @see org.musicontroller.core.searching.ISearcher#searchGeneral(java.lang.String, java.lang.String)
65  	 */
66  	public List<Item> searchGeneral(String username, String toSearch) throws IOException, ParseException {
67  		IndexReader reader = IndexReader.open(FileUtils.getIndexdir());
68  	    Searcher searcher = new IndexSearcher(reader);
69  	    Query query = MultiFieldQueryParser.parse(new String[]{toSearch},new String[]{"contents"},new StandardAnalyzer());
70  	    log.debug("Searching for: " + query.toString("contents"));
71  
72  	    Hits hits = null;
73  	    if (username==null) {
74  	    	hits = searcher.search(query);
75  	    } else {
76  	    	hits = searcher.search(query,new Sort(new SortField[]{SortField.FIELD_SCORE,new SortField("user_"+username.toLowerCase(),SortField.INT,true)}));
77  	    }
78  	    
79  	    List<Item> items = new LinkedList<Item>();
80  	    float score=1;
81  	    for (int i=0;i<50 && i<hits.length() && score>0.1;i++) {
82  	    	Document found = hits.doc(i);
83  	    	score = hits.score(i);
84  	    	
85  	    	try {
86  		    	Long id = Long.parseLong(found.getField("objectid").stringValue());
87  		    	String name = found.getField("name").stringValue();
88  		    	String kind = found.getField("objecttype").stringValue();
89  		    	String excerpt = extractExcerpt(toSearch,found.getField("contents").stringValue());
90  		    	items.add(new Item(id,name,kind,score,excerpt));
91  	    	} catch (Exception e) {
92  	    		log.error("Error adding found document to searchresult: "+found);
93  	    	}
94  	    }
95  	    reader.close();
96  	    
97  	    return items;
98  	}
99  
100 	private String extractExcerpt(String toSearch, String contents) {
101 		String lower = contents.toLowerCase();
102 		String searchlower = toSearch.toLowerCase();
103 		if (lower.contains(searchlower)) {
104 			final int length = 50;
105 			int start = lower.indexOf(searchlower) - length;
106 			int stop = toSearch.length() + start + length*2;
107 			
108 			if (start<0) start=0;
109 			if (stop>contents.length()) stop = contents.length();
110 			
111 			return contents.substring(start,stop);
112 		} else {
113 			return "";
114 		}
115 	}
116 }