練功房推薦書單

  • Google!Android 3手機應用程式設計入門(第四版)
  • 賈伯斯傳(軟皮精裝版)
  • 猛虎出閘制霸版:最新OCP Java SE 6 Programmer專業認證(附原始程式碼及範例檔)
  • SCWCD 5 猛虎出閘:Java Web 應用程式專業認證
关于搜索,有问题求教~  XML
Forum Index » JForum中文社群 JForum Chinese Users Community
Author Message
wu_net2008

八級學員

Joined: 2008-04-30 11:02:50
Messages: 20
Offline

搜索在后台是怎样实现的?我这边搜索的功能无法实现,英文中文都是不行,都是0个结果。search.htm的method已经改为post,请问还有可能是那方面原因?谢谢!
andowson

六段學員
[Avatar]

Joined: 2007-01-02 22:20:40
Messages: 652
Location: 台北
Offline

1.檢查目錄權限是否正確
JForum自2.1.8版起改用Lucene作為搜尋引擎,會自動建立索引檔,產生的索引檔存放的預設目錄是$JFORUM_HOME/WEB-INF/jforumLuceneIndex,如果該目錄不存在JForum會自動建立,故需要將WEB-INF目錄設定為tomcat可寫入才行。

在Unix-like系統上可做如下的設定
chgrp tomcat WEB-INF
chmod 775 WEB-INF

2.檢查編碼設定是否正確
資料庫使用的編碼建議設定為UTF-8,並注意jforum-custom.conf裡面的設定是否也設定正確:
dbencoding=utf-8
encoding=UTF-8

3.檢查Tomcat系統設定是否正確
請勿對Connector加上URIEncoding="UTF-8"的參數,這樣會造成二次轉碼,反而找不到。

4.檢查作業系統預設編碼是否正確
檢查/etc/sysconfig/i18n內容,例如:
LANG="zh_TW.UTF-8"
SUPPORTED="zh_TW.UTF-8:zh_TW:zh"
SYSFONT="latarcyrheb-sun16"

5.search.htm請維持原來的GET method,不要改成POST method。

6.重建索引
到系統管理控制台,點選Lucene統計功能,輸入以時間區間方式,重建一次索引,如果上方的文件數不為0即表示索引建立成功。

This message was edited 2 times. Last update was at 2008-05-29 21:58:46


分享經驗 累積智慧
[WWW] [MSN]
wu_net2008

八級學員

Joined: 2008-04-30 11:02:50
Messages: 20
Offline

项目进行得差不多了,现在搜索的问题还是没有解决,编码都已经进行了设置,还是搜不到中文,问题求解中。。。
andowson

六段學員
[Avatar]

Joined: 2007-01-02 22:20:40
Messages: 652
Location: 台北
Offline

最近一個案子是在Windows Server 2003上安裝JForum,也遇到了中文搜尋的問題,不過這次的問題是字元字編碼的問題。

首先在WebRequestContext.java中插入幾行輸出(System.out.println())以便提供除錯資訊
	/**
	 * Default constructor.
	 * 
	 * @param superRequest Original <code>HttpServletRequest</code> instance
	 * @throws IOException
	 */
	public WebRequestContext(HttpServletRequest superRequest) throws IOException
	{
		super(superRequest);

		this.query = new HashMap();
		boolean isMultipart = false;
		
		String requestType = superRequest.getMethod().toUpperCase();
		String contextPath = superRequest.getContextPath();
		String requestUri = this.extractRequestUri(superRequest.getRequestURI(), contextPath);
		String encoding = SystemGlobals.getValue(ConfigKeys.ENCODING);
		System.out.println("encoding=" + encoding);
		String servletExtension = SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION);
		
		boolean isPost = "POST".equals(requestType);
		boolean isGet = !isPost;
		
		boolean isQueryStringEmpty = (superRequest.getQueryString() == null 
			|| superRequest.getQueryString().length() == 0);
		
		if (isGet && isQueryStringEmpty && requestUri.endsWith(servletExtension)) {
			superRequest.setCharacterEncoding(encoding); 
			this.parseFriendlyURL(requestUri, servletExtension);
		}
		else if (isPost) {
			isMultipart = ServletFileUpload.isMultipartContent(new ServletRequestContext(superRequest));
			
			if (isMultipart) {
			    this.handleMultipart(superRequest, encoding);
			}
		}
		
		if (!isMultipart) {
			boolean isAjax = "XMLHttpRequest".equals(superRequest.getHeader("X-Requested-With"));
			
			if (!isAjax) {
				superRequest.setCharacterEncoding(encoding);
				System.out.println("request.encoding=" + encoding);
			}
			else {
				// Ajax requests are *usually* sent using application/x-www-form-urlencoded; charset=UTF-8.
				// In JForum, we assume this as always true.
				superRequest.setCharacterEncoding("UTF-8");
			}
			
			String containerEncoding = SystemGlobals.getValue(ConfigKeys.DEFAULT_CONTAINER_ENCODING);			
			
			if (isPost) { 
				containerEncoding = encoding;
			}
			System.out.println("containerEncoding=" + containerEncoding);
			for (Enumeration e = superRequest.getParameterNames(); e.hasMoreElements(); ) {
				String name = (String)e.nextElement();
				
				String[] values = superRequest.getParameterValues(name);
				
				if (values != null && values.length > 1) {
					for (int i = 0; i < values.length; i++) {
						System.out.println("before: "+name+"["+i+"]="+values[i]);
						this.addParameter(name, new String(values[i].getBytes(containerEncoding), encoding));						
						System.out.println("after: "+name+"["+i+"]="+new String(values[i].getBytes(containerEncoding), encoding));
					}
				}
				else {
					System.out.println("before: "+name+"="+superRequest.getParameter(name));				    
					this.addParameter(name, new String(superRequest.getParameter(name).getBytes(containerEncoding), encoding));					
					System.out.println("after: "+name+"="+new String(superRequest.getParameter(name).getBytes(containerEncoding), encoding));
				}
			}
			
			if (this.getModule() == null && this.getAction() == null) {
				int index = requestUri.indexOf('?');
				
				if (index > -1) {
					requestUri = requestUri.substring(0, index);
				}
				
				this.parseFriendlyURL(requestUri, servletExtension);
			}
		}
	}

然後在搜尋頁面上的關鍵字欄位輸入「中文」,然後按下搜尋,會出現下列的錯誤訊息:
An error has occurred.

For detailed error information, please see the HTML source code, and contact the forum Administrator.

org.apache.lucene.queryParser.ParseException: Cannot parse '': Encountered "EOF" at line 1, column 0.
Was expecting one of:
NOT ...
"+" ...
"-" ...
"(" ...
"*" ...
QUOTED ...
TERM ...
PREFIXTERM ...
WILDTERM ...
"[" ...
"{" ...
NUMBER ...

在Tomcat的logs目錄下的stdout.log檔案內可以發現到下列的資訊:
encoding=UTF-8
request.encoding=UTF-8
containerEncoding=ISO-8859-1
before: search_keywords=中文
after: search_keywords=??
before: module=search
after: module=search
before: sort_by=relevance
after: sort_by=relevance
before: match_type=all
after: match_type=all
before: action=search
after: action=search
before: search_forum=
after: search_forum=

可以發現,在做轉碼前我們get到的參數值是正確的,但在轉碼後就變成問號了,於是就變成Lucene剔除的符號字元,結果變成搜尋用的關鍵字串是空的。
修改方式就是在迴圈中判斷requestType是否為post,如果是(isPost == true)才轉碼,不然就用原來的值。
			for (Enumeration e = superRequest.getParameterNames(); e.hasMoreElements(); ) {
				String name = (String)e.nextElement();
				
				String[] values = superRequest.getParameterValues(name);
				
				if (values != null && values.length > 1) {
					for (int i = 0; i < values.length; i++) {					    
						if (isPost) {
						    this.addParameter(name, new String(values[i].getBytes(containerEncoding), encoding));
						} else {
						    this.addParameter(name, values[i]);
						} 
					}
				}
				else {				    
					if (isPost) {
					    this.addParameter(name, new String(superRequest.getParameter(name).getBytes(containerEncoding), encoding));
					} else {
					    this.addParameter(name, superRequest.getParameter(name));
					}
				}
			}

這樣再去搜尋就可以了。

This message was edited 2 times. Last update was at 2009-12-10 19:07:08


分享經驗 累積智慧
[WWW] [MSN]
sudiliuxin

十級學員

Joined: 2009-10-20 13:24:41
Messages: 2
Offline

请问一个JFORUM 搜索的问题:
我发表新的主题贴后,LUCENCE可以搜索到,但是我把jforumLuceneIndex的索引删掉之后,JFORUM就不把原来的主题贴做索引引擎了 ,也就是从启动后新发表的主题贴才做索引引擎,请问要怎么修改代码才能够全部重新都做索引引擎

This message was edited 1 time. Last update was at 2009-10-23 19:07:04

andowson

六段學員
[Avatar]

Joined: 2007-01-02 22:20:40
Messages: 652
Location: 台北
Offline

您可以修改 net/jforum/search/LuceneReindexer.java

luceneIndexer.batchCreate(post);

替代為
luceneIndexer.create(post);


然後到管理後台,再重新執行一次從無到有的重新索引即可。

分享經驗 累積智慧
[WWW] [MSN]
acer123

九級學員

Joined: 2009-09-10 14:45:53
Messages: 19
Offline

BTW just curious what is LuceneIndex functionality ? I search it on wiki and it states something like a backup. When i try to execute under Admin control panel i see some files created but when opened are all in ASCII characters. Whats the use of it ?
sybell

十級學員

Joined: 2011-11-03 15:34:30
Messages: 4
Offline

jforum的搜索选项起不作用,选一个版面,但是搜索出来的结果是所有版面的查询结果,是怎么回事?有办法解决么?同时如果设置了关联性和发表时间的参数也不是按照设置规则来查询,为什么?
 
Forum Index » JForum中文社群 JForum Chinese Users Community
Go to: