lucene搜索脚手架

本文旨在做一个lucene的搜索模板,提供类似于优酷的视频搜索服务。

 效果:

基于lucene3.6.1

由于数量少就没有分页,实际上是可以分页的,例子是20个结果一页。

有些重复用相同原理的搜索选项就没弄上去了。

中文分词用的是IKAnalyzer2012.tag的作用在于增加匹配的权重,例子的tag是sfa.

既然是模板,当然主要是用了java设计模式里面的模板方法了。

 建索引的模板:

 1 package index;
 2 
 3 import java.io.File;
 4 import java.io.IOException;
 5 import java.sql.SQLException;
 6 import java.text.ParseException;
 7 import java.util.List;
 8 import java.util.Map;
 9 
10 import javax.sql.DataSource;
11 
12 import org.apache.commons.dbutils.QueryRunner;
13 import org.apache.commons.dbutils.handlers.MapListHandler;
14 import org.apache.lucene.analysis.Analyzer;
15 import org.apache.lucene.index.IndexWriter;
16 import org.apache.lucene.index.IndexWriterConfig;
17 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
18 import org.apache.lucene.store.FSDirectory;
19 import org.springframework.context.ApplicationContext;
20 import org.springframework.context.support.ClassPathXmlApplicationContext;
21 import org.wltea.analyzer.lucene.IKAnalyzer;
22 
23 import com.mchange.v2.c3p0.ComboPooledDataSource;
24 
25 public abstract class Abstract_Index_builder implements Index_Builder {
26     private Analyzer analyzer = new IKAnalyzer();
27 
28     public DataSource get_data_source() {
29         ApplicationContext ctx = new ClassPathXmlApplicationContext(
30                 new String[] { "applicationContext.xml" });//spring配置
31         ComboPooledDataSource c3po_ds = (ComboPooledDataSource) ctx
32                 .getBean("dataSource");//spring bean,也就是c3po连接池的实例
33         return (DataSource) c3po_ds;
34     }
35 
36     public List<Map<String, Object>> do_query(DataSource ds, String sql)
37             throws SQLException {
38         QueryRunner qr = new QueryRunner();//commons dbutils的queryRunner查询数据库
39         List<Map<String, Object>> results = (List<Map<String, Object>>) qr
40                 .query(ds.getConnection(), sql, new MapListHandler());//在继承模板的之类中具体实现查询 
41         return results;
42     }
43 
44     public abstract void add_to_writer(List<Map<String, Object>> data,
45             IndexWriter writer);
46 
47     public void generate_index(String path, String sql) throws IOException,
48             SQLException, ParseException {//开始建索引
49         IndexWriterConfig conf = new IndexWriterConfig(
50                 org.apache.lucene.util.Version.LUCENE_36, analyzer);
51         conf.setOpenMode(OpenMode.CREATE);
52         File file = new File(path);
53         FSDirectory directory = FSDirectory.open(file);
54         IndexWriter writer = new IndexWriter(directory, conf);
55         List<Map<String, Object>> data = do_query(get_data_source(), sql);
56         add_to_writer(data, writer);//写入
57         writer.close();
58     }
59 }

具体的实现子类:

 1 package index;
 2 
 3 import java.io.IOException;
 4 import java.text.ParseException;
 5 import java.text.SimpleDateFormat;
 6 import java.util.Date;
 7 import java.util.List;
 8 import java.util.Map;
 9 
10 import org.apache.lucene.document.Document;
11 import org.apache.lucene.document.Field;
12 import org.apache.lucene.document.NumericField;
13 import org.apache.lucene.document.Field.Index;
14 import org.apache.lucene.document.Field.Store;
15 import org.apache.lucene.index.IndexWriter;
16 
17 public class Generate_Video_Index extends Abstract_Index_builder {
18 
19     @Override
20     public void add_to_writer(List<Map<String, Object>> data, IndexWriter writer) {
21         SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
22         for (int i = 0, len = data.size(); i < len; i++) {
23             Document doc = new Document();
24             Date date = null;
25             try {
26                 date = sdf
27                         .parse(data.get(i).get("video_uploadtime").toString());
28             } catch (ParseException e) {
29                 e.printStackTrace();
30             }
31             Field video_name = new Field("video_name", data.get(i)
32                     .get("video_name").toString(), Store.YES, Index.ANALYZED);
33             Field tag = new Field("tag", data.get(i).get("tag").toString(),
34                     Store.YES, Index.ANALYZED);
35             NumericField video_uploadtime = new NumericField(
36                     "video_uploadtime", Store.YES, true).setLongValue(date
37                     .getTime());//发布时间
38             NumericField duration = new NumericField("duration", Store.YES,
39                     true).setIntValue((int) data.get(i).get("duration"));//片长
40             Field id = new Field("id", data.get(i).get("id").toString(),
41                     Store.YES, Index.NOT_ANALYZED);//用户id
42             NumericField video_type_id = new NumericField("video_type_id",
43                     Store.YES, true).setIntValue((int) data.get(i).get(
44                     "video_type_id"));//分类
45             NumericField chanel_id = new NumericField("chanel_id", Store.YES,
46                     true).setIntValue((int) data.get(i).get("chanel_id"));
47             NumericField video_id = new NumericField("video_id", Store.YES,
48                     true).setIntValue((int) data.get(i).get("video_id"));
49             Field name = new Field("name", data.get(i).get("name").toString(),
50                     Store.YES, Index.NOT_ANALYZED);
51             Field watch = new Field("watch", data.get(i)
52                     .get("video_watchtimes").toString(), Store.YES,
53                     Index.NOT_ANALYZED);//播放次数
54             doc.add(video_id);
55             doc.add(chanel_id);
56             doc.add(video_name);
57             doc.add(tag);
58             doc.add(video_uploadtime);
59             doc.add(id);
60             doc.add(name);
61             doc.add(watch);
62             doc.add(duration);
63             doc.add(video_type_id);
64             try {
65                 writer.addDocument(doc);
66             } catch (IOException e) {
67                 e.printStackTrace();
68             }
69         }
70     }
71 }

调用建立索引模板:

实际上不用把需要展示的所有搜索结果项都写入lucene,只用把id之类的写入就可以了。lucene完成查询后取出id再从数据库查询一遍。例子只是为了简单方便才那样做的。

 1 package index;
 2 
 3 import java.io.IOException;
 4 import java.sql.SQLException;
 5 import java.text.ParseException;
 6 
 7 public class Build_Index {
 8     public static void build_index() throws SQLException, IOException,
 9             java.text.ParseException {
10         Abstract_Index_builder video_index_builder = new Generate_Video_Index();
11         video_index_builder
12                 .generate_index(
13                         "E://lucene/video",
14                         "select user.name,vi.video_id,vi.video_name,vi.video_watchtimes,vi.video_uploadtime,vi.tag,vi.id,vi.duration,type.video_type_id,vi.chanel_id "
15                                 + "from video_info vi inner join user as "
16                                 + "user on vi.id=user.id inner join video_sub_type as sub_type on sub_type.video_sub_type_id=vi.video_sub_type_id inner "
17                                 + "join video_type as type on type.video_type_id=sub_type.video_type_id");
18     }
19 
20     public static void main(String[] args) throws SQLException, IOException,
21             ParseException {
22         Build_Index.build_index();
23     }
24 }

搜索模板:

 1 package search;
 2 
 3 import java.io.File;
 4 import java.io.IOException;
 5 import java.util.List;
 6 import java.util.Map;
 7 
 8 import javax.servlet.http.HttpServletRequest;
 9 
10 import org.apache.lucene.analysis.Analyzer;
11 import org.apache.lucene.index.IndexReader;
12 import org.apache.lucene.search.IndexSearcher;
13 import org.apache.lucene.search.Query;
14 import org.apache.lucene.search.ScoreDoc;
15 import org.apache.lucene.search.TopDocs;
16 import org.apache.lucene.search.TopDocsCollector;
17 import org.apache.lucene.search.TopScoreDocCollector;
18 import org.apache.lucene.search.highlight.Formatter;
19 import org.apache.lucene.search.highlight.Fragmenter;
20 import org.apache.lucene.search.highlight.Highlighter;
21 import org.apache.lucene.search.highlight.QueryScorer;
22 import org.apache.lucene.search.highlight.Scorer;
23 import org.apache.lucene.search.highlight.SimpleFragmenter;
24 import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
25 import org.apache.lucene.store.FSDirectory;
26 import org.apache.struts2.interceptor.ServletRequestAware;
27 import org.wltea.analyzer.lucene.IKAnalyzer;
28 
29 import com.opensymphony.xwork2.ActionSupport;
30 
31 public abstract class Abstract_Search_builder extends ActionSupport implements
32         Search_Builder, ServletRequestAware {//struts2
33     protected Analyzer analyzer = new IKAnalyzer();
34     public HttpServletRequest request;
35     protected int count;
36 
37     public int getCount() {
38         return count;
39     }
40 
41     public void setCount(int count) {
42         this.count = count;
43     }
44 
45     public abstract List<Map<String, Object>> get_search_result(
46             ScoreDoc[] docs, Highlighter highlighter, IndexSearcher search,
47             int count);//获取搜索结果写入request
48 
49     public void setServletRequest(HttpServletRequest request) {
50         this.request = request;
51     }
52 
53     public List<Map<String, Object>> do_search(int start, int offset,
54             TopDocsCollector c, Query query1, String path) throws IOException {
55         FSDirectory d = FSDirectory.open(new File(path));
56         IndexReader r = IndexReader.open(d);
57         IndexSearcher search = new IndexSearcher(r);
58         if (c == null) {//不是分页请求
59             c = TopScoreDocCollector.create(search.maxDoc(), false);
60             offset = search.maxDoc();
61             start = 0;
62         }
63         search.search(query1, c);
64         int count = c.getTotalHits();
65         ScoreDoc[] docs = c.topDocs(offset * start, offset).scoreDocs;
66         Formatter formatter = new SimpleHTMLFormatter("<font color='red'>",
67                 "</font>");
68         Scorer fragmentScore = new QueryScorer(query1);
69         Highlighter highlighter = new Highlighter(formatter, fragmentScore);
70         Fragmenter fragmenter = new SimpleFragmenter(100);
71         highlighter.setTextFragmenter(fragmenter);
72         List<Map<String, Object>> list = get_search_result(docs, highlighter,
73                 search, count);
74         search.close();
75         return list;
76     }
77 }

搜索的实现子类:

  1 package search;
  2 
  3 import java.io.IOException;
  4 import java.sql.SQLException;
  5 import java.text.ParseException;
  6 import java.util.ArrayList;
  7 import java.util.Date;
  8 import java.util.HashMap;
  9 import java.util.List;
 10 import java.util.Map;
 11 
 12 import org.apache.lucene.index.CorruptIndexException;
 13 import org.apache.lucene.queryParser.QueryParser;
 14 import org.apache.lucene.search.BooleanClause;
 15 import org.apache.lucene.search.BooleanQuery;
 16 import org.apache.lucene.search.IndexSearcher;
 17 import org.apache.lucene.search.Query;
 18 import org.apache.lucene.search.ScoreDoc;
 19 import org.apache.lucene.search.Sort;
 20 import org.apache.lucene.search.SortField;
 21 import org.apache.lucene.search.TopDocsCollector;
 22 import org.apache.lucene.search.TopFieldCollector;
 23 import org.apache.lucene.search.TopScoreDocCollector;
 24 import org.apache.lucene.search.highlight.Highlighter;
 25 import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
 26 import org.apache.lucene.util.Version;
 27 
 28 import output.CommonOutput;
 29 import output.Strategy;
 30 
 31 import util.LuceneUtil;
 32 
 33 public class Video_Search extends Abstract_Search_builder {
 34     private String word;
 35     private String tag;
 36     private int start;
 37     private int order_type;
 38     private int limit_date;
 39     private Album_Search album_search;
 40     private Map<String, Object> info = null;
 41     private int offset = 20;
 42     private int watch_filter;
 43     private int time_filter;
 44     private int type_filter;
 45 
 46     public void setAlbum_search(Album_Search album_search) {
 47         this.album_search = album_search;
 48     }
 49 
 50     public int getLimit_date() {
 51         return limit_date;
 52     }
 53 
 54     public void setLimit_date(int limit_date) {
 55         this.limit_date = limit_date;
 56     }
 57 
 58     public int getWatch_filter() {
 59         return watch_filter;
 60     }
 61 
 62     public void setWatch_filter(int watch_filter) {
 63         this.watch_filter = watch_filter;
 64     }
 65 
 66     public int getTime_filter() {
 67         return time_filter;
 68     }
 69 
 70     public void setTime_filter(int time_filter) {
 71         this.time_filter = time_filter;
 72     }
 73 
 74     public int getType_filter() {
 75         return type_filter;
 76     }
 77 
 78     public void setType_filter(int type_filter) {
 79         this.type_filter = type_filter;
 80     }
 81 
 82     public int getOrder_type() {
 83         return order_type;
 84     }
 85 
 86     public void setOrder_type(int order_type) {
 87         this.order_type = order_type;
 88     }
 89 
 90     public int getStart() {
 91         return start;
 92     }
 93 
 94     public void setStart(int start) {
 95         this.start = start;
 96     }
 97 
 98     public String getWord() {
 99         return word;
100     }
101 
102     public void setWord(String word) {
103         this.word = word;
104     }
105 
106     public String getTag() {
107         return tag;
108     }
109 
110     public void setTag(String tag) {
111         this.tag = tag;
112     }
113 
114     public Query complex_video_query(String w, String t, Query q3, Query q4,
115             Query q5) throws ParseException,
116             org.apache.lucene.queryParser.ParseException {
117         QueryParser qp = new QueryParser(Version.LUCENE_36, "video_name",
118                 analyzer);
119         Query q1 = qp.parse(w);
120         QueryParser parser = new QueryParser(Version.LUCENE_36, "tag", analyzer);
121         Query q2 = parser.parse(t);
122         BooleanQuery query1 = new BooleanQuery();
123         query1.add(q1, BooleanClause.Occur.MUST);
124         query1.add(q2, BooleanClause.Occur.SHOULD);
125         LuceneUtil.build_bool_query(query1, q3);
126         LuceneUtil.build_bool_query(query1, q4);
127         LuceneUtil.build_bool_query(query1, q5);//将查询条件组合
128         return query1;
129     }
130 
131     public String video_search() throws IOException, ParseException,
132             InvalidTokenOffsetsException, NumberFormatException,
133             java.text.ParseException, SQLException,
134             org.apache.lucene.queryParser.ParseException {//请求从这里进入
135         Sort sort = null;
136         TopDocsCollector c = null;
137         Query q3 = null;
138         Query q4 = null;
139         Query q5 = null;
140         int max_d = 0;
141         int min_d = 0;
142         switch (getOrder_type()) {//排序
143         case 1:
144             sort = new Sort(new SortField("video_uploadtime", SortField.LONG,
145                     true));
146             break;
147         case 2:
148             sort = new Sort(new SortField("watch", SortField.INT, true));
149             break;
150         default:
151             break;
152         }
153         if (sort == null)
154             c = TopScoreDocCollector
155                     .create(offset * getStart() + offset, false);
156         else
157             c = TopFieldCollector.create(sort, offset * getStart() + offset,
158                     false, false, false, false);
159         switch (getWatch_filter()) {//结果过滤
160         case 1:
161             max_d = 10800;
162             min_d = 3600;
163             break;
164         case 2:
165             max_d = 3600;
166             min_d = 1800;
167             break;
168         case 3:
169             max_d = 1800;
170             min_d = 600;
171             break;
172         case 4:
173             max_d = 600;
174             min_d = 0;
175             break;
176         default:
177             max_d = 0;
178             min_d = 0;
179             break;
180         }
181         if (getWatch_filter() < 5 && getWatch_filter() > 0) {
182             q3 = LuceneUtil.int_range_query(min_d, max_d, "duration");
183         }
184         if (getTime_filter() == 1) {
185             Date before_date = LuceneUtil.getDateBefore(new Date(),
186                     getLimit_date());
187             q4 = LuceneUtil.long_range_query(before_date.getTime(),
188                     new Date().getTime(), "video_uploadtime");
189         }
190         if (getType_filter() != 0)
191             q5 = LuceneUtil.int_range_query(getType_filter(), getType_filter(),
192                     "video_type_id");
193         Query query1 = complex_video_query(getWord(), getTag(), q3, q4, q5);
194         List<Map<String, Object>> list = do_search(getStart(), offset, c,
195                 query1, "E://lucene/video");
196         Strategy strategy1 = new CommonOutput();
197         strategy1.output(list, request, info, "result");
198         request.setAttribute("q", getWord());
199         request.setAttribute("s", getOrder_type());
200         request.setAttribute("wf", getWatch_filter());
201         request.setAttribute("timef", getTime_filter());
202         request.setAttribute("typef", getType_filter());
203         request.setAttribute("ld", getLimit_date());
204         request.setAttribute("cur", getStart());
205         request.setAttribute("count", Math.ceil(this.getCount() / offset));
206         return "success";
207     }
208 
209     @Override
210     public List<Map<String, Object>> get_search_result(ScoreDoc[] docs,
211             Highlighter highlighter, IndexSearcher search, int count) {
212         this.setCount(count);
213         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
214         for (int i = 0; i < docs.length; i++) {
215             int sd = docs[i].doc;
216             Map<String, Object> map = new HashMap<String, Object>();
217             String video_name1 = null;
218             String video_name = null;
219             String name = null;
220             String tag1 = null;
221             String tag = null;
222             String duration = null;
223             String id = null;
224             String watch = null;
225             String video_type_id = null;
226             String video_id = null;
227             try {
228                 video_name1 = search.doc(sd).get("video_name");
229                 if (video_name1.length() > 12)
230                     video_name1 = video_name1.substring(0, 12) + "..";
231                 tag1 = search.doc(sd).get("tag");
232                 duration = search.doc(sd).get("duration");
233                 id = search.doc(sd).get("id");
234                 video_id = search.doc(sd).get("video_id");
235                 name = search.doc(sd).get("name");
236                 watch = search.doc(sd).get("watch");
237                 video_type_id = search.doc(sd).get("video_type_id");
238             } catch (CorruptIndexException e1) {
239                 e1.printStackTrace();
240             } catch (IOException e1) {
241                 e1.printStackTrace();
242             }
243             try {
244                 video_name = highlighter.getBestFragment(analyzer,
245                         "video_name", video_name1);
246                 tag = highlighter.getBestFragment(analyzer, "tag", tag1);
247             } catch (IOException | InvalidTokenOffsetsException e1) {
248                 e1.printStackTrace();
249             }
250             if (tag == null)
251                 tag = tag1;
252             if (video_name == null)
253                 video_name = video_name1;
254             map.put("duration",
255                     LuceneUtil.cal_duration(Integer.parseInt(duration)));
256             // try {
257             // map.put("video_uploadtime",
258             // Long.parseLong(search.doc(sd).get("video_uploadtime")));
259             // } catch (NumberFormatException | IOException e) {
260             // // TODO Auto-generated catch block
261             // e.printStackTrace();
262             // }
263             try {
264                 map.put("duration",
265                         LuceneUtil.cal_duration(Integer.parseInt(duration)));
266                 map.put("video_uploadtime",
267                         LuceneUtil.dateDiff(
268                                 Long.parseLong(search.doc(sd).get(
269                                         "video_uploadtime")),
270                                 new Date().getTime()));
271             } catch (NumberFormatException | ParseException | IOException e) {
272                 e.printStackTrace();
273             }
274             map.put("video_id", video_id);
275             map.put("tag", tag);
276             map.put("video_name", video_name);
277             map.put("id", id);
278             map.put("name", name);
279             map.put("watch", watch);
280             map.put("video_type_id", video_type_id);
281             list.add(map);
282         }
283         return list;
284     }
285 }

工具类:

  1 package util;
  2 
  3 import java.sql.SQLException;
  4 import java.util.Calendar;
  5 import java.util.Date;
  6 import java.util.List;
  7 import java.util.Map;
  8 import java.util.Set;
  9 
 10 import javax.sql.DataSource;
 11 
 12 import org.apache.commons.dbutils.QueryRunner;
 13 import org.apache.commons.dbutils.handlers.MapListHandler;
 14 import org.apache.lucene.search.BooleanClause;
 15 import org.apache.lucene.search.BooleanQuery;
 16 import org.apache.lucene.search.NumericRangeQuery;
 17 import org.apache.lucene.search.Query;
 18 import org.json.JSONArray;
 19 import org.json.JSONObject;
 20 import org.springframework.context.ApplicationContext;
 21 import org.springframework.context.support.ClassPathXmlApplicationContext;
 22 
 23 import com.mchange.v2.c3p0.ComboPooledDataSource;
 24 
 25 public class LuceneUtil {
 26     public static String toJson(List<Map<String, Object>> list)
 27             throws Exception {//转换成json
 28         JSONArray array = new JSONArray();
 29         JSONObject member = null;
 30         for (Map<String, Object> map : list) {
 31             member = new JSONObject();
 32             Set<Map.Entry<String, Object>> sets = map.entrySet();
 33             for (Map.Entry<String, Object> entry : sets) {
 34                 member.put((String) entry.getKey(), (Object) entry.getValue());
 35             }
 36             array.put(member);
 37         }
 38         return array.toString();
 39     }
 40 
 41     public static Query build_bool_query(BooleanQuery q1, Query q2) {
 42         if (q2 != null)
 43             q1.add(q2, BooleanClause.Occur.MUST);
 44         return q1;
 45     }
 46 
 47     public static String cal_duration(int second) {//片长格式化
 48         String h = "0";
 49         String d = "0";
 50         String s = "0";
 51         int temp = second % 3600;
 52         if (second > 3600) {
 53             h = String.valueOf(second / 3600);
 54             if (Integer.parseInt(h) < 10) {
 55                 h = "0" + h;
 56             }
 57             if (temp != 0) {
 58                 if (temp > 60) {
 59                     d = String.valueOf(temp / 60);
 60                     if (Integer.parseInt(d) < 10) {
 61                         d = "0" + d;
 62                     }
 63                     if (temp % 60 != 0) {
 64                         s = String.valueOf(temp % 60);
 65                         if (Integer.parseInt(s) < 10) {
 66                             s = "0" + s;
 67                         }
 68                     }
 69                 } else {
 70                     s = String.valueOf(temp);
 71                     d = "00";
 72                     if (Integer.parseInt(s) < 10) {
 73                         s = "0" + s;
 74                     }
 75                 }
 76             } else {
 77                 d = "00";
 78                 s = "00";
 79             }
 80         } else {
 81             h = "00";
 82             d = String.valueOf(second / 60);
 83             if (Integer.parseInt(d) < 10) {
 84                 d = "0" + d;
 85             }
 86             if (Integer.parseInt(d) % 60 == 0) {
 87 
 88                 h = String.valueOf((Integer.parseInt(d) / 60));
 89                 if (Integer.parseInt(h) < 10) {
 90                     h = "0" + h;
 91                 }
 92                 d = "00";
 93             }
 94             s = "00";
 95             if (second % 60 != 0) {
 96                 s = String.valueOf(second % 60);
 97                 if (Integer.parseInt(s) < 10) {
 98                     s = "0" + s;
 99                 }
100             }
101         }
102         if (h == "00")
103             return d + ":" + s;
104         if (d == "00")
105             return s;
106         return h + ":" + d + ":" + s;
107     }
108 
109     public static String dateDiff(long startTime, long endTime)
110             throws java.text.ParseException {//将上传时间转换为多少日(月,年)前
111         long nd = 1000 * 24 * 60 * 60;
112         long diff = endTime - startTime;
113         long day = diff / nd;
114         if (day > 30 && day < 365)
115             return day / 30 + "月前";
116         if (0 <= day && day <= 30)
117             return day + "天前";
118         if (day > 365)
119             return day / 365 + "年前";
120         return null;
121     }
122     //范围查询
123     public static Query long_range_query(final long min, final long max,
124             final String field) {
125         return NumericRangeQuery.newLongRange(field, min, max, true, true);
126     }
127 
128     public static Query int_range_query(int min, int max, final String field) {
129         return NumericRangeQuery.newIntRange(field, min, max, true, true);
130     }
131 
132     public static Date getDateBefore(Date d, int day) {
133         Calendar now = Calendar.getInstance();
134         now.setTime(d);
135         now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
136         return now.getTime();
137     }
138 
139     public static DataSource get_data_source() {
140         ApplicationContext ctx = new ClassPathXmlApplicationContext(
141                 new String[] { "applicationContext.xml" });
142         ComboPooledDataSource c3po_ds = (ComboPooledDataSource) ctx
143                 .getBean("dataSource");
144         return (DataSource) c3po_ds;
145     }
146 
147     public static List<Map<String, Object>> simple_query(DataSource ds,
148             String sql, Object[] params) throws SQLException {
149         QueryRunner qr = new QueryRunner();
150         List<Map<String, Object>> results = (List<Map<String, Object>>) qr
151                 .query(ds.getConnection(), sql, new MapListHandler(), params);
152         return results;
153     }
154 }

个人感觉优酷的视频搜索应该用的就是lucene或者solr构建的,因为它的搜索域的session cookie中有jsessionid,这个是即便手动从后台代码中显示更换名字都是不行,因为它默认就在servelet中给你加了,除非去改servelet的源码。

另外,lucene建索引的速度比sphinx慢很多,而查询速度也比sphinx慢一点。所以如果应用的大部分不是构建在java上或者应用不大,还是用sphinx就已经可以很好的满足上面那些查询条件的需求了。

转载请注明:TheViper    http://www.cnblogs.com/TheViper

 

posted on 2014-11-10 12:23  TheViper_  阅读(775)  评论(0编辑  收藏  举报