2009-05-30

[JavaScript] 物件導向-類別宣告


// 宣告類別
function Attack(key) {
/*=( 建構子及初始化成員變數 )================== */
// 設定字符表
this.keyStr = key;

// 將字串切割成陣列
this.keyArray = this.keyStr.match(/./gi);

// 進位基底
this.base = this.keyArray.length;

this.passwd = [0];


/*=( 成員函數 )================== */
// 前進一個字符
this.pushPasswd = function(){
var p = this.passwd;
var b = this.base;
var i = 0;

p[i]++;
while(p[i] >= b){
p[i++] = 0;
if(p[i] != undefined){
p[i]++;
}else{
p[i] = 0;
}

}
return this;
};

// 設定初始字串
this.setPasswd = function(str){
this.passwd = [0];

if(str){
var s = str.match(/./gi);
var k = this.keyStr;

for(var i=0,l=s.length; i<l; i++){
num = k.indexOf( str[i] );
if(num<0){ num = 0; }
this.passwd[l-i-1] = num;
}
}
return this;
};

// 取得當前字串
this.getPasswd = function(){
var temp = '';
var k = this.keyArray;
var p = this.passwd;

for(var i=0,l=p.length; i<l; i++){
temp = k[ p[i] ] + temp;
}
return temp;

};
}


// 建立物件
var try1 = new Attack('abcdefghijklmnopqrstuvwxyz0123456789');

// 物件操作
try1.setPasswd('asdf');
try1.getPasswd();
2009-05-29

Picasa 所有的縮圖尺寸(size)

Picasa 在上傳圖片後就會為圖片建立各種尺寸的縮圖
如果想變更預設提供連結的圖片大小
可以修改圖片的 URL 去達成
只是要看這類似亂碼的 URL 會有點累人


以下面這個圖片的 URL 來看:
http://lh6.ggpht.com/_b8lN_UbLoEc/Sfi2pSkc_4I/AAAAAAAAENA/ECO_WzQk2og/s400/as_001.jpg

當中的 s400 就是縮圖的尺寸
簡單的說就是高度與寬度的最大值

Picasa 提供以下的縮圖尺寸:
  • s32
  • s48
  • s64
  • s72
  • s94
  • s104
  • s110
  • s128
  • s160
  • s200
  • s220
  • s288
  • s320
  • s400
  • s512
  • s576
  • s640
  • s720
  • s800
  • s912
  • s1024
  • s1152
  • s1280
  • s1440
  • s1600

如果要取得原始大小的 URL 的話只要去掉 s400 就可以了
例如:
http://lh6.ggpht.com/_b8lN_UbLoEc/Sfi2pSkc_4I/AAAAAAAAENA/ECO_WzQk2og/as_001.jpg

Ajax(XMLHttpRequest) 同步與非同步(異步)連結

首先針對 Internet Explorer 的連結物件做統一的處理,將 ActiveXObject 包裝成與 Mozilla 中的 XMLHttpRequest 相同的物件,這樣我們就可以排除瀏覽器的問題。

/* 針對不同瀏覽器的前置處理宣告 */
if (typeof(XMLHttpRequest)=="undefined" && window.ActiveXObject) {
XMLHttpRequest=function(){
var arrSignatures = [
"MSXML2.XMLHTTP.5.0",
"MSXML2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP",
"Microsoft.XMLHTTP"];
for (var i = 0; i < arrSignatures.length; i++) {
try{
var oRequest = new ActiveXObject(arrSignatures[i]);
return oRequest;
}catch(oError){/*ignore*/}
}
throw new Error("MSXML is not installed on your system.");
};
}



我們可以直接用 XMLHttpRequest 去處理 Ajax 連結,這是以[GET]方式建立[非同步]的傳送連接,如果要使用 POST 做連結請參考之前的文章[Ajax 使用 POST 傳送]。
POST 的差別只在於 open,setRequestHeader,send 這三個地方的設定。

/**=( 以[GET]方式建立[非同步]傳送連接 )====================*/

// 產生要求資料的 URL 及 GET 參數
var sURL = "check_in.php?user=xxxx&pass=xxxx";

// 建立 XMLHttpRequest 物件,並且送要求
var oRequest = new XMLHttpRequest();

// 設定連結方式及位址,並以非同步方式處理
oRequest.open("GET", sURL, true);
/*
void open(
in AUTF8String method, 傳送的方式
in AUTF8String url, 要求的位址
[optional] in boolean async, 同步方式(預設 true 非同步)
[optional] in AString user, 使用者名稱(預設為空字串)
[optional] in AString password 使用者密碼(預設為空字串)
);
*/

// 建立接收狀態的事件處理
oRequest.onreadystatechange = function(){
/*
當狀態變更時都會呼叫此事件
可利用 readyState 取得目前的狀態
所有可能的傳送狀態值如下:
0 (還沒開始)
1 (讀取中)
2 (已讀取)
3 (資訊交換中)
4 (請求完成)
*/
switch(oRequest.readyState){
case 0: // 開始前的程式處理
break;
case 1: // 讀取中的程式處理
break;
case 2: // 已讀取的程式處理
break;
case 3: // 資訊交換中的程式處理
break;
case 4: // 請求完成的程式處理
/* (在此處加入開啟已停用選項的設置) */

/*可以從responseText或responseXML取得傳回的資料*/
// 處理傳回為 200 的 HTTP 狀態碼
if (oRequest.status == 200) {
// 接受資料成功


// 將 responseText 中的文字轉成 JSON 物件
json = eval('('+oRequest.responseText+')');

// 處理其他錯誤 HTTP 狀態碼
}else{
/*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/
alert(oRequest.statusText);
}
break;
}

}

/* (在此處可以加入一些網頁選項停用的設置,以防止重複送出) */

// 送出 Ajax 要求
oRequest.send(null);
/*
以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)
以GET傳送時,這裡只要輸入 null 或是空的
*/

// 強制中斷
//oRequest.abort();
/* 此函數方法可用在必要時,強制終止非同步請求 */



建立[同步]的 Ajax 傳送連接只要將 onreadystatechange 裡的程序移到 send 後面就可以了,如果非必要,最好還是不要以[同步]方式做連結,再處理死結的時候會多一些必要的處理,除非保證連結是 100% 正常且可行的。

/**=( 以[GET]方式建立[同步]傳送連接 )====================*/

// 產生要求資料的 URL 及 GET 參數
var sURL = "check_in.php?user=xxxx&pass=xxxx";

// 建立 XMLHttpRequest 物件,並且送要求
var oRequest = new XMLHttpRequest();

// 設定連結方式及位址,並以同步方式處理
oRequest.open("GET", sURL, false);
/*
void open(
in AUTF8String method, 傳送的方式
in AUTF8String url, 要求的位址
[optional] in boolean async, 同步方式(預設 true 非同步)
[optional] in AString user, 使用者名稱(預設為空字串)
[optional] in AString password 使用者密碼(預設為空字串)
);
*/

/* 開始前的程式處理... */

/* 讀取中的程式處理... */

// 送出 Ajax 要求
oRequest.send(null);
/*
以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)
以GET傳送時,這裡只要輸入 null 或是空的
*/

// 請求完成的程式處理
/*可以從responseText或responseXML取得傳回的資料*/
// 處理傳回為 200 的 HTTP 狀態碼
if (oRequest.status == 200) {
// 接受資料成功

// 將 responseText 中的文字轉成 JSON 物件
json = eval('('+oRequest.responseText+')');

// 處理其他錯誤 HTTP 狀態碼
}else{
/*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/
alert(oRequest.statusText);
}



參考來源:
XMLHttpRequest - MDC
XMLHttpRequest的同步请求和Firefox的问题_网银

爪哇豆的秘密:AJAX深度歷險1(Getting Started)
Ajax内部交流文档
MoztwWiki:AJAX 上手篇
維基百科:AJAX
語言技術:Ajax Gossip
2009-05-23

[Firefox 套件開發] 建立檔案選取對話匡並儲存檔案



//*建立檔案選取對話匡*/
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.
classes["@mozilla.org/filepicker;1"].
createInstance(nsIFilePicker);

// 對話匡標題及開啟形式
fp.init(window, "儲存文件", nsIFilePicker.modeSave);
/*
常數 數值 描述
modeOpen 0 載入一個檔案或目錄
modeSave 1 儲存一個檔案或目錄
modeGetFolder 2 選擇一個資料夾目錄
modeOpenMultiple 3 載入多個檔案
*/


// 預設副檔名
fp.defaultExtension = 'txt';
// 預設檔名
fp.defaultString = 'file_name';
// 檔案類型過濾
fp.appendFilter("純文字檔","*.txt");

// 使用檔案類型過濾
fp.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterXML);
/*
常數 數值 描述
filterAll 0x01 符合 *.* 的副檔名
filterHTML 0x02 符合 *.html, *.htm 的副檔名
filterText 0x04 符合 *.txt 的副檔名
filterImages 0x08 符合 *.png, *.gif, *.jpg, *.jpeg 的副檔名
filterXML 0x10 符合 *.xml 的副檔名
filterXUL 0x20 符合 *.xul 的副檔名
filterApps 0x40 符合系統平台的應用程式類型
*/


// 顯示對話匡
var result = fp.show();

/*
常數 數值 描述
returnOK 0 當使用者點擊對話匡中的"確認"
returnCancel 1 當使用者點擊對話匡中的"取消"
returnReplace 2 當使用者選擇一個已存在的檔案並同意複寫
*/
if (result != nsIFilePicker.returnCancel) {
//建立檔案資料流
var stream = Components.
classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);

// 移除已存在檔案文件
if(fp.file.exists()){fp.file.remove(true);}
// 建立新檔案文件
fp.file.create(fp.file.NORMAL_FILE_TYPE, 0666);

// 開啟檔案資料流
stream.init(fp.file, 0x02, 0x200, null);

var str = "test string"

// 將字串寫入檔案文件
stream.write(str, str.length);

// 關閉檔案資料流
stream.close();
}


參考來源:
Open and Save Dialogs - MDC
nsIFilePicker - MDC
Writing textual data - MDC
File I/O - MDC
nsIOutputStream - MDC

[Firefox 套件開發] 建立檔案選取對話匡並讀取檔案



//*建立檔案選取對話匡*/
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.
classes["@mozilla.org/filepicker;1"].
createInstance(nsIFilePicker);

// 對話匡標題及開啟形式
fp.init(window, "讀取文件", nsIFilePicker.modeOpen);
/*
常數 數值 描述
modeOpen 0 載入一個檔案或目錄
modeSave 1 儲存一個檔案或目錄
modeGetFolder 2 選擇一個資料夾目錄
modeOpenMultiple 3 載入多個檔案
*/


// 預設副檔名
fp.defaultExtension = 'txt';
// 預設檔名
fp.defaultString = 'file_name';
// 檔案類型過濾
fp.appendFilter("純文字檔","*.txt");

// 使用檔案類型過濾
fp.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterXML);
/*
常數 數值 描述
filterAll 0x01 符合 *.* 的副檔名
filterHTML 0x02 符合 *.html, *.htm 的副檔名
filterText 0x04 符合 *.txt 的副檔名
filterImages 0x08 符合 *.png, *.gif, *.jpg, *.jpeg 的副檔名
filterXML 0x10 符合 *.xml 的副檔名
filterXUL 0x20 符合 *.xul 的副檔名
filterApps 0x40 符合系統平台的應用程式類型
*/


// 顯示對話匡
var result = fp.show();

/*
常數 數值 描述
returnOK 0 當使用者點擊對話匡中的"確認"
returnCancel 1 當使用者點擊對話匡中的"取消"
returnReplace 2 當使用者選擇一個已存在的檔案並同意複寫
*/
if (result != nsIFilePicker.returnOK) {
//建立檔案資料流
var stream = Components.
classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
var cstream = Components.
classes["@mozilla.org/intl/converter-input-stream;1"].
createInstance(Components.interfaces.nsIConverterInputStream);

// 開啟檔案資料流
stream.init(fp.file, -1, 0, 0);
// 設定檔案讀取編碼方式
cstream.init(stream, "UTF-8", 0, 0);

var templates='';
let (str = {}) {
// 讀取整個文件,並把它放在 str.value
cstream.readString(-1, str);
templates = str.value;
}

// 顯示檔案內容
alert(templates);


// 關閉檔案資料流
cstream.close();
stream.close();
}


參考來源:
Open and Save Dialogs - MDC
nsIFilePicker - MDC
Reading textual data - MDC
File I/O - MDC
nsIInputStream - MDC
2009-05-21

[JavaScript] 取得選取範圍中的連結

getSelection 這個函數雖然可以取得使用者選取的文字,但要取得所選取的元素時,要用反向的方式去處理。

簡單的說 Selection 並沒有直接提供元素取得的方法,必須透過查驗元素是否在選取範圍內的方式,去找尋被選取的元素。


// 頁面選取的物件
var selection=window.getSelection();

// 取得頁面中所有的連結元素
var links=document.links;

// 掃瞄所有的連結元素
for(var i=0,l=links.length; i<l; i++){
// 檢查連結元素是否在選取的範圍裡
if(selection.containsNode(links[i],true)){
console.log(links[i]);
}
}

[Firefox 套件開發] 取得當前的網頁 DOM 物件及視窗框架


/*
取得當前的網頁 DOM 物件,
這等於平常在網頁中 JavaScript 的 document。
*/
var doc = window.content.document;
// or
var doc = window.top.getBrowser().contentDocument;

// 當要改變視窗的 URL 頁面時
doc.location = "http://www.google.com.tw/";

// 取得指定 ID 的 DOM 元素
var content = doc.getElementById("content");

/*
PS: 這裡的 window 是指整個瀏覽器,
而非一般網頁中的 window,
在開發時別造成混淆了。
*/



/* 取得所有的瀏覽匡,這個物件將會是所有分頁共用的 */
var browser = window.top.getBrowser();

// 當頁面加載結束時的事件
contentOnLoad=function(e){
alert("onLoad");

// 如果事件只需要執行一次,或動態註冊,記得在結束時註銷事件
browser.removeEventListener("load",contentOnLoad,false);
};
// 註冊事件
browser.addEventListener("load",contentOnLoad,false);

2009-05-20

[Firefox 套件開發] CSS 延生屬性

在為了設定 broadcaster 中 window 的底色
無意見找到 Firefox 中 CSS 的延生屬性表
Mozilla CSS Extensions - MDC

當中有蠻多好玩得屬性質
雖然只限於 Mozilla 的瀏覽器

下面的屬性將會顯示你瀏覽器目前所使用的底色:

 -moz-Field 
 -moz-Dialog 
 Window 
 Highlight 

[Firefox 套件開發] 設立快捷鍵

在 Firefox 套件中要建立自己的快捷鍵是非常容易的,只要在 XUL 中設定需要的按鍵及事件的對應就可以了。

<?xml version="1.0"?>

<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

    <!-- 建立快捷鍵 -->
    <keyset>
        <key id="key1"
             modifiers="control"
             key="Q"
             oncommand="alert('crtl+Q')" />

        <key id="key2"
             modifiers="control alt"
             key="C"
             oncommand="alert('crtl+alt+C')" />

        <key id="key3"
             modifiers="shift control"
             key="C"
             oncommand="alert('shift+crtl+C')" />

        <key id="key4"
             keycode="VK_F6"
             oncommand="alert('F6')"/>

        <key id="key5"
             modifiers="shift control"
             key="B"
             command="broadcaster1" />
    </keyset>

</window>


屬性
command
型態:command Id
監測內容的命令來設置編號元素。

disabled
型態:Bool(true,false)
顯示的元素是否被禁用。如果因素設置為True ,該元素被禁用。disabled 的內容通常是繪製灰色文字。如果內容是 disabled,用戶沒有回應的行動,甚至沒有收件人的重點,指揮事件不會發生。

key
型態:字符(character)
觸發鍵的字母值,必要的屬性設置。

keycode
型態:鍵盤按鍵的代碼字串
鍵盤上不是每個按鍵都有字母值,如 F1,Enter,Back...等,這個屬性可用來代替 key 的設置,去設定特殊的按鍵。
下面是常用的按鍵代碼:
VK_CANCELVK_BACKVK_TABVK_CLEAR
VK_RETURNVK_ENTERVK_SHIFTVK_CONTROL
VK_ALTVK_PAUSEVK_CAPS_LOCKVK_ESCAPE
VK_SPACEVK_PAGE_UPVK_PAGE_DOWNVK_END
VK_HOMEVK_LEFTVK_UPVK_RIGHT
VK_DOWNVK_PRINTSCREENVK_INSERTVK_DELETE
VK_0VK_1VK_2VK_3
VK_4VK_5VK_6VK_7
VK_8VK_9VK_SEMICOLONVK_EQUALS
VK_AVK_BVK_CVK_D
VK_EVK_FVK_GVK_H
VK_IVK_JVK_KVK_L
VK_MVK_NVK_OVK_P
VK_QVK_RVK_SVK_T
VK_UVK_VVK_WVK_X
VK_YVK_ZVK_NUMPAD0VK_NUMPAD1
VK_NUMPAD2VK_NUMPAD3VK_NUMPAD4VK_NUMPAD5
VK_NUMPAD6VK_NUMPAD7VK_NUMPAD8VK_NUMPAD9
VK_MULTIPLYVK_ADDVK_SEPARATORVK_SUBTRACT
VK_DECIMALVK_DIVIDEVK_F1VK_F2
VK_F3VK_F4VK_F5VK_F6
VK_F7VK_F8VK_F9VK_F10
VK_F11VK_F12VK_F13VK_F14
VK_F15VK_F16VK_F17VK_F18
VK_F19VK_F20VK_F21VK_F22
VK_F23VK_F24VK_NUM_LOCKVK_SCROLL_LOCK
VK_COMMAVK_PERIODVK_SLASHVK_BACK_QUOTE
VK_OPEN_BRACKETVK_BACK_SLASHVK_CLOSE_BRACKETVK_QUOTE
VK_HELP   


keytext
型態:字串
鍵盤快捷鍵標籤,這段文字將顯示在設有快捷鍵的 menuitem 中,並串接在 label 屬性後面。

modifiers
型態:組合鍵清單
快捷鍵中的組合鍵。組合鍵以空格分隔的或逗號。key 是不存在的平台上,將被分配到其他 key。
  • shift: Shift 鍵。
  • alt: Alt 鍵。在Mac 上是 Option 鍵。因為在 Mac 上文本輸入特別的文字的 Alt+Letter 的組合被預約,與其他的 modifier 聯結被使用。
  • meta: Meta 鍵。在 Mac 上是 Command 鍵。
  • control: Ctrl(Control) 鍵。
  • accel: 用戶的平台上的快捷鍵使用的鑰匙。通常成為使用的價值。
  • access: menu 和其他的要素的訪問鍵。在Windows 上面是 Alt 鍵。與要素的 accesskey 聯結被使用。
  • any:代表上述的全部,表示任意的 modifier key。

oncommand
型態:Script code
此事件處理程序被激活時,該命令要求。這是選擇一個菜單項時所發生的用戶命令或按下鍵盤快捷鍵分配給它。

參考來源:
key - MDC
keyset - MDC
firefox扩展开发(七) : 键盘快捷键

[PHP] 取得 URL 頁面上的 title 內容


<?php
/*
功能: 取得 URL 頁面上的 <title> 內容

參數:$_POST['url']
*/

// 設定最長執行的秒數
ini_set ("expect.timeout", 30);
set_time_limit(30);

// 檢查 URL
if(!isset($_POST['url']) || $_POST['url'] == ''){
echo "URL 錯誤";
exit;
}


/* 取得 URL 頁面資料 */
// 初始化 CURL
$ch = curl_init();

// 設定 URL
curl_setopt($ch, CURLOPT_URL, $_POST['url']);
// 讓 curl_exec() 獲取的信息以資料流的形式返回,而不是直接輸出。
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
// 在發起連接前等待的時間,如果設置為0,則不等待
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 0);
// 設定 CURL 最長執行的秒數
curl_setopt ($ch, CURLOPT_TIMEOUT, 30);

// 嘗試取得文件內容
$store = curl_exec ($ch);


// 檢查文件是否正確取得
if (curl_errno($ch)){
echo "無法取得 URL 資料";
//echo curl_error($ch);/*顯示錯誤訊息*/
exit;
}

// 關閉 CURL
curl_close($ch);


// 解析 HTML 的 <head> 區段
preg_match("/<head.*>(.*)<\/head>/smUi",$store, $htmlHeaders);
if(!count($htmlHeaders)){
echo "無法解析資料中的 <head> 區段";
exit;
}

// 取得 <head> 中 meta 設定的編碼格式
if(preg_match("/<meta[^>]*http-equiv[^>]*charset=(.*)(\"|')/Ui",$htmlHeaders[1], $results)){
$charset = $results[1];
}else{
$charset = "None";
}

// 取得 <title> 中的文字
if(preg_match("/<title>(.*)<\/title>/Ui",$htmlHeaders[1], $htmlTitles)){
if(!count($htmlTitles)){
echo "無法解析 <title> 的內容";
exit;
}

// 將 <title> 的文字編碼格式轉成 UTF-8
if($charset == "None"){
$title=$htmlTitles[1];
}else{
$title=iconv($charset, "UTF-8", $htmlTitles[1]);
}
echo $title;
}

[PHP] 裁切圖片並縮小至指定大小


<?php
/*
功能:裁切圖片並縮小至指定大小

參數:
$_GET['f'] 圖檔名稱:0001.jpg

$_GET['x'] 圖片裁切水平方向的起始位址(px):10
$_GET['y'] 圖片裁切垂直方向的起始位址(px):20

$_GET['w'] 圖片裁切選取的寬度(px):300
$_GET['h'] 圖片裁切選取的高度(px):200
*/

// 縮小圖片的指定大小(px)
$decreaseSize=160;


// 設定 header 中的圖片類型
header("Content-type:image/jpg");

// 檢查是否有給予圖片名稱,否則結束裁切
if (!isset($_GET['f']) || $_GET['f']==''){ exit; }

// 設定 header 中的圖片名稱
header("Content-Disposition:filename=".$_GET['f']);

// 開啟暫存目錄中的圖片
$source = @imageCreateFromJpeg("/tmp/".$_GET['f']);

if (!$source){
// 圖片開啟錯誤...
exit;
}


// 取得圖片原始寬度與高度
$sourceWidth = imagesX($source);
$sourceHeight = imagesY($source);


/* 裁切圖片 */
// 圖片選取的寬度與高度
$cropWidth = intval($_GET['w']);
$cropHeight = intval($_GET['h']);

// 檢查裁切寬度是否在範圍裡
if (!$cropWidth || $cropWidth > $sourceWidth){ // 寬度為零或超過最大寬度
$cropWidth = $sourceWidth;
}elseif ($cropWidth < $decreaseSize){ // 低於最小寬度
$cropWidth=$decreaseSize;
}

// 檢查裁切高度是否在範圍裡
if (!$cropHeight || $cropHeight > $sourceHeight){ // 高度為零或超過最大高度
$cropHeight = $sourceHeight;
}elseif ($cropHeight < $decreaseSize){ // 低於最小高度
$cropHeight = $decreaseSize;
}


// 圖片選取的起始位址
$cropX = intval($_GET['x']);
$cropY = intval($_GET['y']);

// 檢查起始位址
if ($cropX > ($sourceWidth-$cropWidth)){
$cropX = $sourceWidth-$cropWidth;
}
if ($cropY > ($sourceHeight-$cropHeight)){
$cropY = $sourceHeight-$cropHeight;
}


// 建立裁切所需要的圖片空間
$crop = imageCreateTrueColor($cropWidth, $cropHeight);

// 複製選定的圖片範圍(剪裁圖片)
imageCopy(
$crop,
$source,
0,
0,
$cropX,
$cropY,
$cropWidth,
$cropHeight
);


/*縮小圖片 */
// 計算縮圖尺寸
if ($cropWidth<$cropHeight) {
$decreaseWidth = $decreaseSize;
$decreaseHeight = intval($cropHeight*$decreaseSize/$cropWidth);
} else {
$decreaseHeight=$decreaseSize;
$decreaseWidth = intval($cropWidth*$decreaseSize/$cropHeight);
}

// 建立縮圖所需要的圖片空間
$decrease = imageCreateTrueColor($decreaseWidth, $decreaseHeight);

// 複製並縮小圖片
imageCopyResampled(
$decrease,
$crop,
0,
0,
0,
0,
$decreaseWidth,
$decreaseHeight,
$cropWidth,
$cropHeight
);


// 顯示圖片
imageJpeg($decrease);


// 關閉圖片
imageDestroy($source);
imageDestroy($crop);
imageDestroy($decrease);


相關文章:
php 圖檔上傳檢查
在固定大小的排版中做圖片選取
MooCrop 正方形選取( Square )
2009-05-13

[Firefox 套件開發] 預設樣式 (Style classes)

Mozilla Developer Center 中找到 Style classes 所列出的樣式,為了明確的瞭解詳細屬性,找了一下在 Firefox 中的原始碼,除了官網中所列出的樣式外,你也可以使用其他預設的樣式。

其他的預設樣式,可以將 C:\Program Files\Mozilla Firefox\chrome 下的 classic.jar 解壓縮,就可以看到許多的預設樣式,像 chrome://browser/skin/browser.css(C:\Program Files\Mozilla Firefox\chrome\classic\skin\classic\browser\browser.css) 中的 tabs-closebutton , bookmark-item 等等都是不錯用的樣式,可以多加利用。



/*=[ alert-icon ]==================*/
/*=[ error-icon ]==================*/
/*=[ message-icon ]==================*/
/*=[ question-icon ]==================*/
.message-icon,
.alert-icon,
.error-icon,
.question-icon {
width: 32px; height: 32px;
}
.message-icon { /*圖片不存在*/
list-style-image: url("chrome://global/skin/icons/Message.png");
}
.alert-icon {
list-style-image: url("chrome://global/skin/icons/Warning.png");
}
.error-icon {
list-style-image: url("chrome://global/skin/icons/Error.png");
}
.question-icon {
list-style-image: url("chrome://global/skin/icons/Question.png");
}

Firefox 3.0.10 預設圖



/*=[ chromeclass-toolbar ]==================*/
window[chromehidden~="menubar"] .chromeclass-menubar,
window[chromehidden~="directories"] .chromeclass-directories,
window[chromehidden~="status"] .chromeclass-status,
window[chromehidden~="extrachrome"] .chromeclass-extrachrome,
window[chromehidden~="location"] .chromeclass-location,
window[chromehidden~="location"][chromehidden~="toolbar"] .chromeclass-toolbar,
window[chromehidden~="toolbar"] .chromeclass-toolbar-additional{
display: none;
}
prefwindow[chromehidden~="toolbar"] .chromeclass-toolbar{
display: none;
}


/*=[ groove ]==================*/
separator.groove,
separator.groove[orient="horizontal"] {
border-top: 1px solid ThreeDShadow;
border-bottom: 1px solid ThreeDHighlight;
height: 0px;
margin-top: 0.4em;
margin-bottom: 0.4em;
}
separator.groove[orient="vertical"] {
border-left: 1px solid ThreeDShadow;
border-right: 1px solid ThreeDHighlight;
-moz-margin-start: 0.4em;
-moz-margin-end: 0.4em;
}


/*=[ header ]==================*/
.header {
font-weight : bold;
}
textbox.header {
-moz-margin-start : 0;
}


/*=[ indent ]==================*/
.indent {
-moz-margin-start : 23px;
}


/*=[ listcell-iconic ]==================*/
.listcell-iconic {
-moz-binding: url("chrome://global/content/bindings/listbox.xml#listcell-iconic");
}
listcell[type="checkbox"].listcell-iconic {
-moz-binding: url("chrome://global/content/bindings/listbox.xml#listcell-checkbox-iconic");
}


/*=[ listitem-iconic ]==================*/
.listitem-iconic {
-moz-binding: url("chrome://global/content/bindings/listbox.xml#listitem-iconic");
}
listitem[type="checkbox"].listitem-iconic {
-moz-binding: url("chrome://global/content/bindings/listbox.xml#listitem-checkbox-iconic");
}


/*=[ menuitem-iconic ]==================*/
menu.menu-iconic > .menu-iconic-left,
menuitem.menuitem-iconic > .menu-iconic-left {
-moz-appearance: menuimage;
}
menu.menu-iconic > .menu-iconic-left > .menu-iconic-icon,
menuitem.menuitem-iconic > .menu-iconic-left > .menu-iconic-icon {
/* reduce icon-text crowding */
-moz-margin-start: -1px;
-moz-margin-end: 1px;
}


/*=[ menuitem-non-iconic ]==================*/
menuitem.menuitem-non-iconic {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menubutton-item");
}


/*=[ monospace ]==================*/
.monospace {
font-family : monospace;
}


/*=[ plain ]==================*/
.plain {
margin: 0px !important;
border: none;
padding: 0px;
}

/* ::::: plain buttons ::::: */
button.plain {
border: 0px !important;
margin: 0px !important;
padding: 0px !important;
}

/* ::::: plain textbox ::::: */
textbox.plain {
-moz-appearance: none !important;
padding: 0px !important;
margin: 0px !important;
border: none !important;
}


/*=[ small-margin ]==================*/
.small-margin {
margin : 1px 2px 1px 2px;
}


/*=[ statusbarpanel-iconic ]==================*/
/*=[ statusbarpanel-iconic-text ]==================*/
/*=[ statusbarpanel-menu-iconic ]==================*/
.statusbarpanel-iconic,
.statusbarpanel-iconic-text,
.statusbarpanel-menu-iconic {
padding: 0px 1px 0px 1px;
}


/*=[ text-link ]==================*/
.console-row-code[selected="true"],
.console-row-content[selected="true"] > .console-row-file > .console-error-source > .text-link {
color: inherit !important;
}
richlistitem[selected="true"] .text-link {
color: inherit;
}

/* class for text with a 'link' appearance */
.text-link {
color : blue;
text-decoration : underline;
border : 1px solid transparent;
}
.text-link:focus {
color : red;
border : 1px dotted -moz-DialogText;
}
.text-link:hover {
cursor : pointer;
}
.text-link:hover:active {
color : red;
}
.text-link[visited="true"] {
color : purple;
}


/*=[ thin ]==================*/
/* thinner separators (50% size) */
separator.thin, separator.thin[orient="horizontal"] {
height: 0.5em;
}
separator.thin[orient="vertical"] {
width: 0.5em;
}


/*=[ tree-splitter ]==================*/
.tree-splitter {
width: 0px;
max-width: 0px;
min-width: 0% ! important;
min-height: 0% ! important;
-moz-box-ordinal-group: 2147483646;
}


/*=[ treecol-image ]==================*/
.treecol-image {
padding: 0px 1px;
}


列表外的其他樣式


/* inset areas */
.inset {
border-left : 1px solid ThreeDShadow;
border-top : 1px solid ThreeDShadow;
border-right : 1px solid ThreeDHighlight;
border-bottom : 1px solid ThreeDHighlight;
margin : 0px 5px 5px 5px;
}


.box-inset {
margin: 2px 4px;
border: 2px solid;
-moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
-moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
-moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
-moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
background-color: -moz-Field;
color: -moz-FieldText;
}


/* formatting */
.groove-top {
border-top : 2px groove ThreeDFace;
}
.groove-right {
border-right : 2px groove ThreeDFace;
}
.groove-left {
border-left : 2px groove ThreeDFace;
}
.groove-bottom {
border-bottom : 2px groove ThreeDFace;
}


.outset {
border-left : 1px solid ThreeDHighlight;
border-top : 1px solid ThreeDHighlight;
border-right : 1px solid ThreeDShadow;
border-bottom : 1px solid ThreeDShadow;
}
.outset-top-bottom {
border-top : 1px solid ThreeDHighlight;
border-bottom : 1px solid ThreeDShadow;
}


/* groove separators (0 padding, for dividing effects) */
separator.groove-thin {
border-top: 1px solid ThreeDShadow;
border-bottom: 1px solid ThreeDHighlight;
height: 0px;
}
separator[orient="vertical"].groove-thin {
border-left: 1px solid ThreeDShadow;
border-right: 1px solid ThreeDHighlight;
}


.larger-text {
font-size : larger;
}

.smaller-text {
font-size : smaller;
}


.box-padded {
padding : 5px;
}


.spaced {
margin : 3px 5px 4px 5px;
}


.wizard-box {
padding : 20px 44px 10px 44px;
}


.caption-text {
margin-top: 0px !important;
margin-bottom: 0px !important;
-moz-margin-start: 1px !important;
-moz-margin-end: 2px !important;
}


.treecol-text {
margin: 0px !important;
}
2009-05-03

find 詳細指令及範例整理 [Linux]

find -遞歸地在層次目錄中處理文件

find [path] [expression]
[path]啟始路徑
[expression]查詢參數


選項 OPTIONS

所有的選項都總是返回真值,它們總會被執行,除非放在表達式中執行不到的地方。因此,清楚起見,最好把它們放在表達式的開頭部分。
-daystart
從當日起始時開始而不是從24小時之前,計算時間(for -amin, -atime, -cmin, -ctime, -mmin, and -mtime)。
-depth
先處理目錄的內容再處理目錄本身,(廣度優先搜尋法則)。
# 從文件系統的根目錄開始搜尋一個名為 CON.FILE 的文件。
find / -name "CON.FILE" -depth
-follow
不檢索符號鏈接。隱含了-noleaf。
-help, --help
列出 find 的命令行用法的概要,然後退出。
-maxdepth levels
進入命令行參數指定的目錄下層目錄時,最深不超過levels(一個非負整數)層。 `-maxdepth 0'意味著只在命令行參數指定的目錄中執行測試和動作。
# 在目錄樹的前三個級別中搜尋日誌文件。
find / -maxdepth 3 -name "*log"

# 只搜尋當前一層目錄下的 C 語言文件。
find . -maxdepth 1 -name “*.c”
-mindepth levels
不在levels(一個非負整數)層之內執行任何測試和動作。 `-mindepth 1'意味著處理所有的文件,除了命令行參數指定的目錄中的文件。
-mount
不進入處於其它文件系統之上的目錄。可以用-xdev代替,從而和一些其他版本的 find 兼容。
# 從當前目錄開始搜尋位於本文件系統中文件名以XC結尾的文件。
find . -name "*.XC" -mount

find / -name "*.txt" -mount 2> /dev/null
-noleaf
不為“目錄中子目錄數量比硬連接數少2”這種假設做優化。這個選項在搜索那些不遵循UNIX文件系統鏈接約定的文件系統時用,比如CD- ROM,MS-DOS文件系統或AFS卷的加載點。在普通的UNIX文件系統中,每個目錄至少有兩個硬連接,它的名字和它的'.'條目。另外,它的子目錄 (假如有)還會各有一個'..'鏈接到它。在 find 檢索一個目錄時,發現子目錄數比它的連接數少二時,它就知道目錄中的其他條目並非目錄(而是目錄樹中的葉(`leaf')節點)。除非需要檢索的是這個葉節點,否則沒必要去處理它。這樣可以帶來很大的搜索速度提升。
-version, --version
打印find的版本號然後退出。
-xdev
不進入處於其他文件系統之上的目錄。
find / -name "*.txt" -xdev 2> /dev/null

測試 TESTS

數字參數可以這樣給出:
+n
是比 n 大,
-n
是比 n 小,
n
正好是 n 。
-amin n
對文件的最近一次訪問是在n分鐘之前。
# 搜尋當前目錄下在5分鐘內被訪問過的文件。
find . -amin -5

# 搜尋在系統中最後10分鐘訪問的文件。
find / -amin -10
-anewer file
對文件的最近一次訪問比file修改時間要晚。如果命令行中-follow在-anewer之前,(也只有在這種情況下) -anewer會受-follow的影響。
-atime n
對文件的最近一次訪問是在n*24小時之前。
# 搜尋在系統中最後48小時訪問的文件。
find / -atime -2
-cmin n
對文件狀態的建立時間是在n分鐘之前。
-cnewer file
對文件狀態的最近一次修改比file修改時間要晚。如果命令行中-follow在-cnewer之前,(也只有在這種情況下) -cnewer會受-follow的影響。
-ctime n
對文件狀態的建立時間是在n*24小時之前。
-empty
文件是空的普通文件或者空目錄。
# 搜尋空文件。
find test -empty

# 搜尋在系統中為空的文件或者文件夾。
find / -empty
-false
總是false。
-fstype type
文件處於type類型的文件系統之上。有效的文件系統類型在不同版本的Unix中是不同的;一些Unix 中的不完全的文件系統類型列表是這樣:ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K.你可以用-printf加上%F指令來查看你的文件系統的類型。
find / -name "*.txt" -fstype vfat 2> /dev/null
-gid n
文件的數字形式的組ID是n。
# 列出由ID為100的組擁有的目錄。
find / -type d -gid 100
-group gname
文件屬於gname (也允許使用數字形式的組ID).
# 在/apps目錄下搜尋群組為 gem 的文件。
find /apps -group gem -print

# 搜尋在系統中 group 屬於 cat 的文件。
find / -group cat
-ilname pattern
和-lname類似,但是匹配時是不區分大小寫的。
-iname pattern
和-name類似,但是匹配時是不區分大小寫的。例如,`fo*' and `F??'模式與文件名`Foo', `FOO', `foo', `fOo'等等相匹配。
-inum n
文件的i結點數是n。
-ipath pattern
和-path類似,但是匹配時是不區分大小寫的。
-iregex pattern
和-regex類似,但是匹配時是不區分大小寫的。
-links n
文件有n個鏈接。
-lname pattern
文件是一個與pattern匹配的符號鏈接。元字符不會對`/'或`.'做特殊處理。
-mmin n
對文件數據的最近一次修改是在n分鐘之前。
# 搜尋在最近1小時內修改的所有文件。
find . -mmin -60

# 搜尋恰好在1小時時修改的所有文件。
find . -mmin 60

# 搜尋1小時以前修改的所有文件。
find . -mmin +1

# 搜尋在系統中最後5分鐘裡修改過的文件。
find / -mmin -5
-mtime n
對文件數據的最近一次修改是在n*24小時之前。
# 將過去系統上面 24 小時內有更動過內容 (mtime) 的檔案列出。
find / -mtime 0
find / –mtime –1

# 在當前目錄中搜尋更改時間在5日以上的文件。
find . -mtime +5

# 在系統根目錄下搜尋更改時間在5日以內的文件。
find / -mtime -5

# 在/var/adm目錄下搜尋更改時間在3日以前的文件。
find /var/adm -mtime +3
-name pattern
基本的文件名(將路徑去掉了前面的目錄)與shell模式pattern相匹配。元字符(`*', `?',還有`[]' )不會匹配文件名開頭的`.' 。使用-prune來略過一個目錄及其中的文件。查看-path的描述中的範例。
# 找出檔名為 passwd 這個檔案。
find / -name passwd

# 在當前目錄中搜尋任何副檔名為“java”的文件。
find . -name "*.java"

# 在/usr、/home /tmp 目錄搜尋所有 jar 文件。
find /usr /home /tmp -name "*.jar"

#在當前目錄中搜尋文件名以一個大寫字母開頭的文件。
find . -name "[A-Z]*" -print

# 在/etc目錄中搜尋文件名以host開頭的文件。
find /etc -name "host*" -print

# 在當前目錄搜尋文件名以兩個小寫字母開頭,跟著是兩個數字,最後是.txt的文件(ax37.txt)。
find . -name "[a-z][a-z][0-9][0-9].txt"
-newer file
對文件的最近一次修改比file修改時間要晚。如果命令行中-follow在-newer之前,(也只有在這種情況下) -newer會受-follow的影響。用在分辨兩個檔案之間的新舊關係是很有用。
# 搜尋更改時間在比temp文件新的文件。
find . -newer temp

# 尋找 /etc 底下的檔案,如果檔案日期比 /etc/passwd 新就列出。
find /etc -newer /etc/passwd
-nouser
沒有符合文件的數字形式的用戶ID的用戶。
# 搜尋系統中不屬於任何人的檔案。
find / -nouser

# 在當前目錄下搜尋使用者名稱非(ftp)的檔案
find . -nouser ftp
-nogroup
沒有符合文件的數字形式的組ID的組。
# 在系統根目錄開始搜尋無效群組的所有文件。
find / -nogroup

# 在當前目錄下搜尋群組名稱非(ftp)的檔案
find . -nogroup ftp
-path pattern
文件名與shell模式pattern相匹配。元字符不會對`/'或`.'做特殊處理。
# 因此,例如:
find . -path './sr*sc'

# 如果存在'./src/misc'的話,會將它打印出來。想要忽略一個完整的目錄樹,應當使用-prune而不是檢查目錄樹中所有的文件。
# 例如:要跳過'src/emacs'目錄和其中所有的文件和子目錄,把其他找到的文件打印出來,應當這樣:
find . -path './src/emacs' -prune -o -print

# 在當前目錄下搜尋 ./pics/pic_01.jpg, ./01/pics/pic_a1.jpg, ./02/pics/01/pic_aa.jpg 這些檔案
find . -path '*pics/*pic_*.jpg'
-perm mode
文件的權限位恰好是mode (八進製或符號)。 Symbolic modes use mode 0 as a point of departure.
# 在當前目錄下搜尋文件權限位為755的文件。
find . -perm 755

find . -type f -perm a=rwx

find . -type f -perm 777
-perm -mode
所有的權限位mode都被設置了的文件。
# 在當前目錄下搜尋檔案權限大於(744)的檔案,(744,774)
find . -perm -744
-perm +mode
任何權限位mode被設置了的文件。
# 搜尋檔案當中含有 SGID 或 SUID 或 SBIT 的屬性。
find / -perm +7000 

# 在當前目錄下搜尋檔案權限小於(744)的檔案,(600,444)
find . -perm +744
-regex pattern
文件名與正則表達式pattern匹配。這是對整個路徑的匹配,不是搜索文件。例如,要匹配名為`./fubar3'的文件,可以使用正則表達式`.*bar.'或者`.*b.*3',但是不能用`b.*r3'。
# 搜尋當前文件夾及子文件夾裡的同時含有b字符和3字符的文件。
find . -regex ‘.*b.*3′

# 在當前目錄下搜尋 pic_01.jpg, pic_03.jpg, pic_03.jpg 這些檔案
find . -regex '.*pic_[0-9]+\.jpg'
-size n[bckw]
文件使用了n單位個存儲單元。 可用單位如下:
  • `b' 512-byte blocks (預設)
  • `c' bytes
  • `w' 2-byte words
  • `k' Kilo bytes (1024 bytes)
  • `M' Mega bytes (1048576 bytes)
  • `G' Giga bytes (1073741824 bytes)
大小不會計入indirect blocks,但是會計入沒有真正分配空間的疏鬆文件中的塊。
# 找出系統中,大於 1MB 的檔案。
find / -size +1M

# 在當前目錄下搜尋長度超過10塊的文件(一塊等於512字節)。
find . -size +10

# 在當前目錄下搜尋文件長度大於 1M 字節的文件。
find . -size +1M

# 在 /home/apache 目錄下搜尋文件長度恰好為 100 字節的文件。
find /home/apache -size 100c
-true
總是true。
-type c
文件是c類型的。 類型可取值如下:
  • b 特殊塊文件(緩衝的)
  • c 特殊字符文件(不緩衝)
  • d 目錄
  • p 命名管道(FIFO)
  • f 普通文件
  • l 符號鏈接
  • s 套接字
  • D 門(Solaris特有)
# 在/etc目錄下搜尋所有的目錄。
find /etc -type d

# 搜尋當前文件系統中的所有目錄並排序。
find . -type d | sort

# 在當前目錄下搜尋除目錄以外的所有類型的文件。
find . ! -type d 

# 在/etc目錄下搜尋所有的符號鏈接文件。
find /etc -type l

# 找出 /var 目錄下,檔案類型為 Socket 的檔名有哪些?
find /var -type s

# 搜尋 /usr 目錄中的所有符號鏈接。
find /usr -type l
-uid n
文件的數字形式的用戶ID是n 。
-used n
文件最後一次存取是在最後一次修改它的狀態的n天之後。
-user uname
文件的所有者是uname (也可以使用數字形式的用戶ID).
# 在家目錄中搜尋文件的使用者為 sam 的文件。
find ~ -user sam

# 在 /etc 目錄下搜尋文件的使用者為 uucp 的文件。
find /etc -user uucp

# 搜尋 /home 底下屬於 vbird 的檔案。
find /home -user vbird
-xtype c
和-type相同,除非文件是一個符號鏈接。對於符號鏈接:如果沒有給出-follow ,如果文件是一個指向c類型文件的鏈接,那麼返回true;如果給出了-follow ,如果c是`l'那麼返回true。換句話說,對於符號鏈接,-xtype檢查那些-type不檢查的文件。

動作 ACTIONS

-delete
將搜尋出來的檔案刪除,如果成功刪除將回傳 ture。如果刪除失敗將丟出錯誤訊息。
# 刪除使用者名稱為(ftp)的檔案
find . -user ftp -delete
-exec command
執行command;如果命令返回狀態值0,那麼exec返回true。所有 find 其餘的命令行參數將作為提供給命令的參數,直到遇到一個由`;'組成的參數為止。命令的參數中,字符串`{}'將以正在處理的文件名替換。所有的`{}'都會被替換,不僅是在單獨的一個參數中。有些版本的 find 不是這樣做的。這些參數可能需要用`\'來escape或者用括號括住,防止它們被shell展開。命令是從起始目錄執行的。
# 搜尋當前目錄下的所有普通文件,並在 -exec 選項中使用 ls -l 命令將它們列出。   
find . -type f -exec ls -l {  }

# 在/logs目錄中搜尋更改時間在5日以前的文件並刪除它們。
find logs -type f -mtime +5 -exec rm {  }

# 列出 /usr/bin 目錄中的鏈接以及它所指向的文件。
find /usr/bin -type l -name "z*" -exec ls -l {}

# 搜索所有零字節文件並將它們移至/tmp/zerobyte文件夾。
find test -type f -size 0 -exec mv {} /tmp/zerobyte
-fls file
返回true;類似-ls但是像-fprint那樣寫入file。
-fprint file
返回true;將文件全名打印到文件file中。如果運行find時file不存在,那麼它將被創建。如果它存在,它將被覆蓋。文件名``/dev/stdout'' 和``/dev/stderr''會作特殊處理;它們分別指的是標準輸出和標準錯誤輸出。
-fprint0 file
返回true;類似-print0但是像-fprint那樣寫入file。
-fprintf file format
返回true;類似-printf但是像-fprint那樣寫入file。
find . -fprintf a.txt '%p\n'
-ok command
類似-exec但是會先向用戶詢問(在標準輸入);如果回應不是以`y'或`Y'起始則不會運行command而是返回false。
# 在當前目錄中搜尋所有文件名以 .conf 結尾、更改時間在5日以上的文件,並刪除它們,只不過在刪除之前先給出提示。
find . -name "*.conf"  -mtime +5 -ok rm {  }
-print
返回true;在標準輸出打印文件全名,然後是一個換行符。
# 搜尋當前用戶家目錄下的所有文件。
find ~ -print

# 將輸出重定向到一個文件。
find / -print > masterfilelist.out
-print0
返回true;在標準輸出打印文件全名,然後是一個null字符。這樣可以使得處理find的輸出的程序可以正確地理解帶有換行符的文件名。
-printf format
返回true;在標準輸出打印format ,解釋`\' escape還有`%'指令。字段寬度和精度可以像C函數`printf'那樣來指定。與-print不同的是, -printf在字符串末端不會添加一個新行。可用的escape和指令如下:
\a警告鈴聲
\b回退
\c立即停止以當前格式輸出,刷新輸出設備。
\f表格結束
\n新行
\r換行
\t水平tab
\v豎直tab
\\輸出自身`\'
\NNNASCII編碼是NNN(八進制)的字符
在一個`\'字符後面使用任何其他字符會被作為普通的字符,因此它們都會被打印出來。
%%輸出自身`%'
%a文件最後一次存取的時間。格式是C函數`ctime'返回值的格式。
%Ak文件最後一次存取的時間。格式以k指定,可以是`@'或者是C函數`strftime'的指令格式。下面列出了k可用的值;有一些並不是在所有系統上都可用,因為不同系統中`strftime'也不同。

  • @ 從Jan. 1, 1970, 00:00 GMT起的秒數

時間字段:
  • H 小時(00..23)
  • I 小時(01..12)
  • k 小時( 0..23)
  • l 小時( 1..12)
  • M 分鐘(00..59)
  • p 本地的AM或者PM
  • r 12小時格式的時間(hh:mm:ss [AP]M)
  • S 秒(00..61)
  • T 24小時格式的時間(hh:mm:ss)
  • X 本地的時間表示方法(H:M:S)
  • Z 時區(例如,EDT),如果不能決定時區就是空


日期字段:
  • a 本地一星期中每天的名稱的縮寫(Sun..Sat)
  • A 本地一星期中每天的全名,可變長度(Sunday..Saturday)
  • b 本地每月的名稱的縮寫(Jan..Dec)
  • B 本地每月的全名,可變長度(January..December)
  • c 本地的日期和時間表示(Sat Nov 04 12:02:33 EST 1989)
  • d 一個月當中的日子(01..31)
  • D 日期(mm/dd/yy)
  • h 與b相同
  • j 一年當中的日子(001..366)
  • m 月份(01..12)
  • U 以星期日作為每週起始,一年當中的星期(00..53)
  • w 一星期當中的日子(0..6)
  • W 以星期一當作每週起始,一年當中的星期(00..53)
  • x 本地的日期表示(mm/dd/yy)
  • y 年份的最後兩位(00..99)
  • Y 年份(1970...)

%b文件大小,以512字節的塊為單位(四捨五入)。
%c文件狀態最後一次修改的時間。格式是C函數`ctime'返回值的格式。
%Ck文件狀態最後一次修改的時間。格式以k指定,類似於%A。
%d文件在目錄樹中的深度;0意味著文件是一個命令行參數。
%f去掉了前面的目錄的文件名(只剩下最後的成分)。
%F文件所在文件系統的類型;這個值可以為-fstype所用。
%g文件的組名,如果組沒有名稱就是數字形式的組ID。
%G文件的數字形式的組ID。
%h文件名的前面的目錄部分(僅除去最後的成分)。
%H據以找到了文件的命令行參數。
%i文件的i結點號(16進制)。
%k文件大小,以1kB的塊為單位(四捨五入)。
%l符號鏈接的目標(如果文件不是一個符號鏈接,那麼結果是空字符串)。
%m文件的權限位(8進制)。
%n文件的硬連接數。
%p文件名。
%P文件名,去掉了據以找到了文件的命令行參數的名稱部分。
%s文件大小,以字節為單位。
%t文件最後一次修改的時間。格式是C函數`ctime'返回值的格式。
%Tk文件最後一次修改的時間。格式以k指定,類似於%A。
%u文件的用戶名,如果用戶沒有名稱就是數字形式的用戶ID。
%U文件的數字形式的用戶ID。
在一個`%'字符後面使用任何其他字符,`%'將被忽略(但是其他字符會被打印出來)。
find . -printf '%p\n'
-prune
如果沒有給出-depth則返回true;不進入當前目錄。如果給出了-depth則返回false;沒有效果。
-ls
返回true;以`ls -dils'格式在標準輸出列出文件。塊以1kB字節為單位計數,除非設置了環境變量POSIXLY_CORRECT,那樣的話會使用512字節的塊。
# 列出 /usr/bin 目錄中的鏈接以及它所指向的文件。
find /usr/bin -type l -name "z*" -ls

運算符OPERATORS

以優先級高低順序排列:
( expr )
強制為優先
! expr
如果expr是false則返回true
# 在 /tmp 目錄中搜尋所有不屬於 panda 的文件。
find /tmp ! -user panda
-not expr
與! expr相同
expr1 expr2
與(隱含的默認運算符);如果expr1為false則不會執行expr2
expr1 -a expr2
與expr1 expr2相同
expr1 -and expr2
與expr1 expr2相同
# 搜尋 /tmp 目錄中大於100000000字節並且在48小時內修改的文件。
find /tmp -size +10000000c -and -mtime +2
expr1 -o expr2
或;如果expr1為true則不會執行expr2
expr1 -or expr2
與expr1 -o expr2相同
# 在 / 目錄下搜尋文件的使用者為 fred 或 george 的文件。
find / -user fred -or -user george

# 要在 /usr/sam 目錄下搜尋不在 dir1 子目錄之內的所有文件。
find /usr/sam -path "/usr/sam/dir1" -prune -or -print

# 避開多個文件夾。
find /usr/sam \( -path /usr/sam/dir1 -or -path /usr/sam/file1 \) -prune -o -print

# 搜尋未列在 /etc/passwd 或 /etc/group 文件中的文件。
find / -nouser -or -nogroup

# 搜尋 SGID 和 SUID 特殊訪問權限的文件。
find / \( -perm -2000 -or -perm -4000 \) -ls

# 在當前目錄下搜尋使用者名稱為(ftp)且權限為(744)的檔案或是群組名稱為(ftp)的檔案
find . \(-user ftp -perm 744\) -or \(-group ftp\)

find /usr/sam \(-path /usr/sam/dir1 -or -path /usr/sam/file1 \) -prune -or -name "temp" -print
expr1 , expr2
列表;expr1和expr2都會被執行。 expr1的值被忽略,列表的值是expr2的值


參考來源:
find - Linux Command - Unix Command
China Linux Forum-中文man page计划

Linux文件查找命令find,xargs详述 | LinuxSir.Org
鳥哥的 Linux 私房菜 -- 檔案與目錄管理
Linux Find 命令精通指南
《find技巧》-“linux命令五分系列”之一 | linux大棚
find指令摘要by yanni
Linux下find命令详解 - 系统管理交流区
Linux find命令详解 - Linux&Unix - 其实我一点也不NB
linux的find查找命令用法 - 不知疲倦的猪

我常用的 Firefox 外掛套件及配置 9.05

我必裝的小工具
Adblock Plus
用來阻擋頁面中的廣告,還有一些不想看到的圖片及 Flash,加快網頁開啟的速度。
IE View
當及時需要使用 IE 開啟網頁時,右鍵選單中的快速功能。
Easy DragToGo
簡單的拖曳手勢,讓新分頁開啟連結、搜尋文字和儲存圖片更容易。
FireBug 螢火蟲
網頁開發必要工具。
FireCookie for FireBug
檢視並管理網頁所使用的 cookie。
Tab Wheel Scroll
用滑鼠滾輪切換分頁。
FlashGot
讓 Firefox 更快速呼叫外部下載工具。
Pronounce
即時英文單字發音。
CHM Reader
讓 Firefox 可以開啟 MS 的 chm 說明文件。
Google 工具列
Google 推出的好用工具列。
Google 筆記本
隨時隨地將看到的網頁加入"Google 筆記本"裡面。



工具列的配置
自訂 Firefox 工具列的配置
將所有的小工具安裝,並在首頁按鈕上點選右鍵中的『自訂』。

自訂 Firefox 工具列的配置
開始拖移自己常用的小工具。

自訂 Firefox 工具列的配置
關閉用不到的工具列。

自訂 Firefox 工具列的配置
完成。
2009-05-02

MySQL 全文檢索引擎 - Sphinx

Sphinx 官方網站



介绍


引用自:Sphinx速成指南

Sphinx 是一個基於SQL的全文檢索引擎,可以結合MySQL,PostgreSQL做全文搜索,它可以提供比數據庫本身更專業的搜索功能,使得應用程序更容易實現專業化的全文檢索。 Sphinx特別為一些腳本語言設計搜索API接口,如PHP,Python,Perl,Ruby等,同時為MySQL也設計了一個存儲引擎插件。


Sphinx的特性:
  • 高速索引(在新款CPU上,近10 MB/秒);
  • 高速搜索(2-4G的文本量中平均查詢速度不到0.1秒);
  • 高可用性(單CPU上最大可支持100 GB的文本,100M文檔);
  • 提供良好的相關性排名
  • 支持分佈式搜索;
  • 提供文檔摘要生成;
  • 提供從MySQL內部的插件式存儲引擎上搜索
  • supports boolean, phrase, and word proximity queries;
  • 支持每個文檔多個全文檢索域(默認最大32個);
  • 支持每個文檔多屬性;
  • 支持斷詞;
  • 支持單字節編碼與UTF-8編碼;
  • supports English stemming, Russian stemming, and Soundex for morphology;
  • 支持MySQL(MyISAM和InnoDB表都支持);
  • 支持PostgreSQL.




重點須知

在你決定是否採用此搜尋引擎前,先瞭解他的應用方式:
  • 提供多種查詢方式與權重計算,具有 BM25 關鍵字計算,權重計算方式無法變更,但能作外部索引加權計算。
  • 非網頁爬蟲的模式,是直接對 DataBase 或 XML 作數據索引。
  • 沒有點擊率的計算,需要自行處理。
  • 搜尋結果不包含原始資料,需要自行處理。



安裝 Sphinx 及 Mysql+SphinxSE

# [安裝 Sphinx 及 Mysql+SphinxSE]
# 
# 下載 Sphinx 及 Mysql
wget http://lxr.mysql.com/archives/mysql-5.1/mysql-5.1.31.tar.gz
wget http://www.sphinxsearch.com/downloads/sphinx-0.9.8.1.tar.gz

# 解壓縮 Sphinx 及 Mysql
tar zxvf mysql-5.1.31.tar.gz
tar zxvf sphinx-0.9.8.1.tar.gz

# 安裝 Sphinx
cd sphinx-0.9.8.1/
./configure
make -j$(grep processor /proc/cpuinfo |wc -l)
make install

# 複製 SphinxSE Engine 至 Mysql
cd ..
cp -R ./sphinx-0.9.8.1/mysqlse ./mysql-5.1.31/storage/sphinx

# 安裝 Mysql
# 必要函式庫 automake autoconf libtool libncurses5-dev bison
cd mysql-5.1.31/
sh BUILD/autorun.sh
./configure --with-plugins=sphinx
make
make install



範例環境

這裡用一個簡單的 Blog 範例來模擬接下來的設定
主要由文章和回應的架構來說明一些主要的觀念
-- 資料庫: `sphinx_test`
-- 建立日期: 2009-3-30
-- 設計版本: 1.0
--
SET NAMES 'UTF8';

DROP DATABASE IF EXISTS `sphinx_test`;
CREATE DATABASE `sphinx_test` DEFAULT CHARACTER SET utf8 
COLLATE utf8_unicode_ci;
USE `sphinx_test`;

-- @ blog_texts(Blog文章)
CREATE TABLE `blog_texts` (
`BlogId` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`Title` CHAR(80) NOT NULL                     COMMENT '標題',
`Text` TEXT NOT NULL                          COMMENT '文章內容',
`InsertDate` DATETIME NOT NULL                COMMENT '建立日期',
PRIMARY KEY(`BlogId`)  
) ENGINE = INNODB COMMENT = '故事文章';
-- -----------------------------------------------------------------

-- @ blog_comments(Blog回應)
CREATE TABLE `blog_comments` (
`Id` INT UNSIGNED NOT NULL AUTO_INCREMENT  COMMENT '主鍵',
`BlogId` INT UNSIGNED NOT NULL             COMMENT '文章 ID',
`Text` TEXT NOT NULL                       COMMENT '回應內容',
`UpdateDate` DATETIME NOT NULL             COMMENT '更新時間',

PRIMARY KEY(`Id`),  
INDEX(`BlogId`),
FOREIGN KEY(`BlogId`)REFERENCES blog_texts(`BlogId`)ON DELETE CASCADE
) ENGINE = INNODB COMMENT = 'Blog 回應';



sphinx.conf 概述

設定檔的主要架構由四個區塊組成:
  • 定義資料來源的形式
  • 定義索引及分詞方式
  • 配置 indexer 所使用的 memory 及 IO存取設定
  • 配置 searchd 的服務端口及查詢數量等項關設定

source 來源名稱1{
# 資料來源設定
}
index 索引名稱1{
source=來源名稱1
# 索引設定
}

source 來源名稱2{
# 資料來源設定
}
index 索引名稱2{
source = 來源名稱2
# 索引設定
}

indexer{
# indexer 配置選項
}
searchd{
# searchd 配置選項
}



sphinx.conf 配置詳解

預設的 conf 位址: /usr/local/etc/sphinx.conf
#
# Sphinx configuration file sample
#
# WARNING! While this sample file mentions all available options,
# it contains (very) short helper descriptions only. Please refer to
# doc/sphinx.html for details.
#

###############################################################
## data source definition
###############################################################

source s_tit
{
# 資料來源的類型。必要設定項,沒有預設值。
# 已知類型 mysql , pgsql , xmlpipe , xmlpipe2。
type           = mysql

# SQL 主機連接的 IP。必要設定項,沒有預設值。
# 僅適用於SQL數據源(mysql,pgsql)。
sql_host       = localhost

# SQL 主機連接的 port 選擇性設定,預設 mysql(3306),及 pgsql(5432)。
# 僅適用於SQL數據源(mysql,pgsql)。
# 這個設定必須依附在 sql_host 下。
sql_port       = 3306  # optional, default is 3306

# 資料庫用戶名稱,必要設定項,沒有預設值。
sql_user       = root

# 資料庫用戶密碼,必要設定項,沒有預設值。
sql_pass       = 0000

# 資料庫名稱,必要設定項,沒有預設值。
sql_db         = sphinx_test

# 資料庫 local 端連結介面,選擇性設定,預設為空。
#sql_sock       = /tmp/mysql.sock 

# MySQL 傳輸壓縮,可將索引建立時的傳輸量,預設為 0(不壓縮)。
#mysql_connect_flags = 32


# 預先查詢。選擇性,可重複,預設是空。僅適用於SQL數據源(mysql,pgsql)。
# 可用來做索引前的初始設定,如編碼設定、緩衝區大小、是否快取暫存
sql_query_pre  = SET NAMES utf8
sql_query_pre  = SET SESSION query_cache_type=OFF


# 主要文件擷取查詢。必要設定項,沒有預設值。僅適用於SQL數據源(mysql,pgsql)。
# 查詢指令允許使用 JOIN 及子查詢,對於資料表不能使用 AS,但資料欄位可以
sql_query      = SELECT `BlogId`,`Title`,`InsertDate` FROM `blog_texts`


# 設定過濾條目,被設定的欄位將不會列入索引的範圍,之後可以作為查詢時的過濾條件,0.9.8版支援下列類型。
sql_attr_timestamp   = InsertDate
#sql_attr_uint = group_id
#sql_attr_bool = is_deleted # will be packed to 1 bit
#sql_attr_str2ordinal = author_name
#sql_attr_float = long_radians 
#sql_attr_multi = uint tag from ranged-query; \
#   SELECT id, tag FROM tags WHERE id>=$start AND id<=$end; \
#   SELECT MIN(id), MAX(id) FROM tags


# 與 sql_query_pre 的功能相同,但用於索引結束後呼叫的指令  
#sql_query_post = DROP TABLE my_tmp_table


#sql_query_info       =SELECT * FROM `blog_texts` WHERE `BlogId`=$id

}

#------------------------------------------------------------------------
source s_txt
{
type           = mysql
sql_host       = localhost
sql_user       = root
sql_pass       = 0000
sql_db         = sphinx_test
sql_port       = 3306
sql_query_pre  = SET NAMES utf8
sql_query_pre  = SET SESSION query_cache_type=OFF
sql_query      = SELECT `BlogId`,`Text`,`InsertDate` FROM `blog_texts`

sql_attr_timestamp   = InsertDate

sql_ranged_throttle  = 0
sql_query_info       =SELECT * FROM `blog_texts` WHERE `BlogId`=$id
}

#------------------------------------------------------------------------
source s_comment
{
type           = mysql
sql_host       = localhost
sql_user       = root
sql_pass       = 0000
sql_db         = sphinx_test
sql_port       = 3306
sql_query_pre  = SET NAMES utf8
sql_query_pre  = SET group_concat_max_len=1048576
sql_query_pre  = SET SESSION query_cache_type=OFF
sql_query     = \
SELECT \
`blog_comments`.`BlogId`, \
GROUP_CONCAT(`blog_comments`.`Text`)AS`CommentText`, \
COUNT(`blog_comments`.`BlogId`)AS`CommentNum`, \
`blog_texts`.`InsertDate` \
FROM \
`blog_texts` \
INNER JOIN \
`blog_comments` \
ON `blog_texts`.`BlogId`=`blog_comments`.`BlogId` \
GROUP BY `blog_comments`.`BlogId` \

sql_attr_uint        = CommentNum
sql_attr_timestamp   = InsertDate

sql_ranged_throttle  = 0
sql_query_info       =SELECT * FROM `blog_texts` WHERE `BlogId`=$id
}





###############################################################
### index definition
###############################################################

index s_tit
{
# 索引類型。預設為空(索引為簡單本地索引)。設定值有空字串或 "distributed"
#type           = distributed

# 指定索引的來源,必須是上面的來源名稱
source          = s_tit


# 索引記錄存放的目錄
path            = /var/data/s_tit


# 文件屬性值存儲模式,預設值為 extern,可設定的屬性有 'none', 'extern' 及 'inline'. 
docinfo         = extern 


# 鎖定記憶體緩衝區段。預設為 0(不鎖定)
mlock           = 0


# 適用的形態前置處理器名單。預設為空(不應用任何前處理器)。
# 可設定的屬性有 'none', 'stem_en', 'stem_ru', 'stem_enru', 'soundex', and 'metaphone'.
# 這段在中文情況下不能使用,否則會導致無法啟動 searchd 服務。
morphology      = none


# 停用詞文件清單(以空白分隔),預設為空。
# 在清單中的 word 將不會加到索引庫裡。
#stopwords      = /usr/local/sphinx/data/stopwords.txt


# 詞形字典,預設為空。可以設定 word 之間的關連性。
# wordforms.txt 
#   walks > walk
#   walked > walk
#   walking > walk
#
#wordforms      = /usr/local/sphinx/data/wordforms.txt

# 保留字例外文件,預設為空。
# exceptions.txt
#   MS Windows => ms windows
#   Microsoft Windows => ms windows
#   C++ => cplusplus
#   c++ => cplusplus
#   C plus plus => cplusplus
#
#exceptions     = /usr/local/sphinx/data/exceptions.txt

# exceptions 與 wordforms 的區別
#  *exceptions 是區分大小寫的, wordforms沒有;
#  *exceptions 允許檢測序列標記, wordforms 只能處理單一的 word;
#  *exceptions 可以使用 charset_table 中沒有的特殊符號,wordforms 完全遵從 charset_table 中的字符;
#  *exceptions 在大字典上性能會下降,wordforms 則對百萬級的條目應對自如;  



# 最短的關鍵字長度
min_word_len    = 1 


# 編碼格式
charset_type    = utf-8


# 指定 UTF-8 的編碼表
charset_table   = U+FF10..U+FF19->0..9,0..9,U+FF41..U+FF5A->a..z,\
U+FF21..U+FF3A->a..z,A..Z->a..z,a..z,U+0149,U+017F,U+0138,U+00DF,\
U+00FF,U+00C0..U+00D6->U+00E0..U+00F6,U+00E0..U+00F6,\
U+00D8..U+00DE->U+00F8..U+00FE,U+00F8..U+00FE,U+0100->U+0101,\
U+0101,U+0102->U+0103,U+0103,U+0104->U+0105,U+0105,U+0106->U+0107,\
U+0107,U+0108->U+0109,U+0109,U+010A->U+010B,U+010B,U+010C->U+010D,\
U+010D,U+010E->U+010F,U+010F,U+0110->U+0111,U+0111,U+0112->U+0113,\
U+0113,U+0114->U+0115,U+0115,U+0116->U+0117,U+0117,U+0118->U+0119,\
U+0119,U+011A->U+011B,U+011B,U+011C->U+011D,U+011D,U+011E->U+011F,\
U+011F,U+0130->U+0131,U+0131,U+0132->U+0133,U+0133,U+0134->U+0135,\
U+0135,U+0136->U+0137,U+0137,U+0139->U+013A,U+013A,U+013B->U+013C,\
U+013C,U+013D->U+013E,U+013E,U+013F->U+0140,U+0140,U+0141->U+0142,\
U+0142,U+0143->U+0144,U+0144,U+0145->U+0146,U+0146,U+0147->U+0148,\
U+0148,U+014A->U+014B,U+014B,U+014C->U+014D,U+014D,U+014E->U+014F,\
U+014F,U+0150->U+0151,U+0151,U+0152->U+0153,U+0153,U+0154->U+0155,\
U+0155,U+0156->U+0157,U+0157,U+0158->U+0159,U+0159,U+015A->U+015B,\
U+015B,U+015C->U+015D,U+015D,U+015E->U+015F,U+015F,U+0160->U+0161,\
U+0161,U+0162->U+0163,U+0163,U+0164->U+0165,U+0165,U+0166->U+0167,\
U+0167,U+0168->U+0169,U+0169,U+016A->U+016B,U+016B,U+016C->U+016D,\
U+016D,U+016E->U+016F,U+016F,U+0170->U+0171,U+0171,U+0172->U+0173,\
U+0173,U+0174->U+0175,U+0175,U+0176->U+0177,U+0177,U+0178->U+00FF,\
U+00FF,U+0179->U+017A,U+017A,U+017B->U+017C,U+017C,U+017D->U+017E,\
U+017E,U+0410..U+042F->U+0430..U+044F,U+0430..U+044F,U+05D0..U+05EA,\
U+0531..U+0556->U+0561..U+0586,U+0561..U+0587,U+0621..U+063A,U+01B9,\
U+01BF,U+0640..U+064A,U+0660..U+0669,U+066E,U+066F,U+0671..U+06D3,\
U+06F0..U+06FF,U+0904..U+0939,U+0958..U+095F,U+0960..U+0963,\
U+0966..U+096F,U+097B..U+097F,U+0985..U+09B9,U+09CE,U+09DC..U+09E3,\
U+09E6..U+09EF,U+0A05..U+0A39,U+0A59..U+0A5E,U+0A66..U+0A6F,\
U+0A85..U+0AB9,U+0AE0..U+0AE3,U+0AE6..U+0AEF,U+0B05..U+0B39,\
U+0B5C..U+0B61,U+0B66..U+0B6F,U+0B71,U+0B85..U+0BB9,U+0BE6..U+0BF2,\
U+0C05..U+0C39,U+0C66..U+0C6F,U+0C85..U+0CB9,U+0CDE..U+0CE3,\
U+0CE6..U+0CEF,U+0D05..U+0D39,U+0D60,U+0D61,U+0D66..U+0D6F,\
U+0D85..U+0DC6,U+1900..U+1938,U+1946..U+194F,U+A800..U+A805,\
U+A807..U+A822,U+0386->U+03B1,U+03AC->U+03B1,U+0388->U+03B5,\
U+03AD->U+03B5,U+0389->U+03B7,U+03AE->U+03B7,U+038A->U+03B9,\
U+0390->U+03B9,U+03AA->U+03B9,U+03AF->U+03B9,U+03CA->U+03B9,\
U+038C->U+03BF,U+03CC->U+03BF,U+038E->U+03C5,U+03AB->U+03C5,\
U+03B0->U+03C5,U+03CB->U+03C5,U+03CD->U+03C5,U+038F->U+03C9,\
U+03CE->U+03C9,U+03C2->U+03C3,U+0391..U+03A1->U+03B1..U+03C1,\ 
U+03A3..U+03A9->U+03C3..U+03C9,U+03B1..U+03C1,U+03C3..U+03C9,\
U+0E01..U+0E2E,U+0E30..U+0E3A,U+0E40..U+0E45,U+0E47,U+0E50..U+0E59,\
U+A000..U+A48F,U+4E00..U+9FBF,U+3400..U+4DBF,U+20000..U+2A6DF,\
U+F900..U+FAFF,U+2F800..U+2FA1F,U+2E80..U+2EFF,U+2F00..U+2FDF,\
U+3100..U+312F,U+31A0..U+31BF,U+3040..U+309F,U+30A0..U+30FF,\
U+31F0..U+31FF,U+AC00..U+D7AF,U+1100..U+11FF,U+3130..U+318F,\
U+A000..U+A48F,U+A490..U+A4CF


# 指明分詞法讀取詞典文件的位置,當啟用分詞法時,為必填項。
# 在使用 LibMMSeg 作為分詞庫時,需要確保詞典文件uni.lib在指定的目錄下。
# 再使用 LibMMSeg 分詞外掛時,這個設定值才有效,不然在建立索引時會出錯。
#charset_dictpath = dict


# 忽略的字符列表,預設為空。
#ignore_chars   = U+AD


# 索引的最小前綴長度,預設為0(不索引前綴)。
#min_prefix_len = 3


# 索引的最小中綴長度,預設為0(不索引中綴)。
#min_infix_len  = 3


# 做前綴索引的字段列表,預設為空(所有字段均為前綴索引模式)。
#prefix_fields  = url, domain


# 做中綴索引的字段列表,預設為空(所有字段均為中綴索引模式)。
#infix_fields   = url, domain


# 允許前綴/中綴索引上的星號語法(或稱萬用字符)預設為 0(不使用通配符),這是為了與0.9.7版本的兼容性。設定值有 0 和 1。
enable_star     = 1


#分詞,設定值有 0,1,如果要搜索中文,請指定為 1
ngram_len       = 1


# 分詞字符,中文搜索必要設定。
ngram_chars     = U+4E00..U+9FBF,U+3400..U+4DBF,U+20000..U+2A6DF,\
U+F900..U+FAFF,U+2F800..U+2FA1F,U+2E80..U+2EFF,U+2F00..U+2FDF,\
U+3100..U+312F,U+31A0..U+31BF,U+3040..U+309F,U+30A0..U+30FF,\
U+31F0..U+31FF,U+AC00..U+D7AF,U+1100..U+11FF,U+3130..U+318F,\
U+A000..U+A48F,U+A490..U+A4CF


# 短語邊界字符列表,預設為空。 
#phrase_boundary = ., ?, !, U+2026


# 是否從輸入全文數據中去除 HTML 標記。預設為 0。設定值有 0(禁用),1(啟用)。 
html_strip      = 0


# 去除 HTML 標籤時要索引標籤語言的屬性列表,預設為空(不索引標記語言屬性)。
# 指定被保留並索引的 HTML 標記語言屬性,即使其他 HTML 標記被刪除。
html_index_attrs      = img=alt,title; a=title;


# HTML 標籤列表,不僅這些標籤本身會被刪除,標籤之間的文字內容也會被刪除。預設為空(不刪除任何元素的內容)。 
html_remove_elements  = style, script
}

index dist_tit
{
# 索引類型。預設為空(索引為簡單本地索引)。設定值有空字串或 "distributed"
type            = distributed


# 分佈式索引(distributed index)中的本地索引聲明,可以設定多個,預設為空。
local           = s_tit


# 分佈式索引(distributed index)中的遠程代理和索引聲明,可以設定多個,預設為空。 
agent           = localhost:3313:remote1
agent           = localhost:3314:remote2,remote3


# 遠程代理的最大連接時間,單位為毫秒,預設為 1000(1 sec)。
agent_connect_timeout  = 1000


# 遠程代理的最大查詢時間,單位為毫秒,預設為 3000(3 sec)。
agent_query_timeout    = 3000


# 預先開啟全部索引文件還是每次查詢時再開啟索引。預設為0(不預先開啟)。
#preopen        = 1
}


#------------------------------------------------------------------------
index s_txt
{
source          = s_txt
path            = /var/data/s_txt
docinfo         = extern
mlock           = 0
morphology      = none
min_word_len    = 1 
charset_type    = utf-8
charset_table   = U+FF10..U+FF19->0..9,0..9,U+FF41..U+FF5A->a..z,\
U+FF21..U+FF3A->a..z,A..Z->a..z,a..z,U+0149,U+017F,U+0138,U+00DF,\
U+00FF,U+00C0..U+00D6->U+00E0..U+00F6,U+00E0..U+00F6,\
U+00D8..U+00DE->U+00F8..U+00FE,U+00F8..U+00FE,U+0100->U+0101,\
U+0101,U+0102->U+0103,U+0103,U+0104->U+0105,U+0105,U+0106->U+0107,\
U+0107,U+0108->U+0109,U+0109,U+010A->U+010B,U+010B,U+010C->U+010D,\
U+010D,U+010E->U+010F,U+010F,U+0110->U+0111,U+0111,U+0112->U+0113,\
U+0113,U+0114->U+0115,U+0115,U+0116->U+0117,U+0117,U+0118->U+0119,\
U+0119,U+011A->U+011B,U+011B,U+011C->U+011D,U+011D,U+011E->U+011F,\
U+011F,U+0130->U+0131,U+0131,U+0132->U+0133,U+0133,U+0134->U+0135,\
U+0135,U+0136->U+0137,U+0137,U+0139->U+013A,U+013A,U+013B->U+013C,\
U+013C,U+013D->U+013E,U+013E,U+013F->U+0140,U+0140,U+0141->U+0142,\
U+0142,U+0143->U+0144,U+0144,U+0145->U+0146,U+0146,U+0147->U+0148,\
U+0148,U+014A->U+014B,U+014B,U+014C->U+014D,U+014D,U+014E->U+014F,\
U+014F,U+0150->U+0151,U+0151,U+0152->U+0153,U+0153,U+0154->U+0155,\
U+0155,U+0156->U+0157,U+0157,U+0158->U+0159,U+0159,U+015A->U+015B,\
U+015B,U+015C->U+015D,U+015D,U+015E->U+015F,U+015F,U+0160->U+0161,\
U+0161,U+0162->U+0163,U+0163,U+0164->U+0165,U+0165,U+0166->U+0167,\
U+0167,U+0168->U+0169,U+0169,U+016A->U+016B,U+016B,U+016C->U+016D,\
U+016D,U+016E->U+016F,U+016F,U+0170->U+0171,U+0171,U+0172->U+0173,\
U+0173,U+0174->U+0175,U+0175,U+0176->U+0177,U+0177,U+0178->U+00FF,\
U+00FF,U+0179->U+017A,U+017A,U+017B->U+017C,U+017C,U+017D->U+017E,\
U+017E,U+0410..U+042F->U+0430..U+044F,U+0430..U+044F,U+05D0..U+05EA,\
U+0531..U+0556->U+0561..U+0586,U+0561..U+0587,U+0621..U+063A,U+01B9,\
U+01BF,U+0640..U+064A,U+0660..U+0669,U+066E,U+066F,U+0671..U+06D3,\
U+06F0..U+06FF,U+0904..U+0939,U+0958..U+095F,U+0960..U+0963,\
U+0966..U+096F,U+097B..U+097F,U+0985..U+09B9,U+09CE,U+09DC..U+09E3,\
U+09E6..U+09EF,U+0A05..U+0A39,U+0A59..U+0A5E,U+0A66..U+0A6F,\
U+0A85..U+0AB9,U+0AE0..U+0AE3,U+0AE6..U+0AEF,U+0B05..U+0B39,\
U+0B5C..U+0B61,U+0B66..U+0B6F,U+0B71,U+0B85..U+0BB9,U+0BE6..U+0BF2,\
U+0C05..U+0C39,U+0C66..U+0C6F,U+0C85..U+0CB9,U+0CDE..U+0CE3,\
U+0CE6..U+0CEF,U+0D05..U+0D39,U+0D60,U+0D61,U+0D66..U+0D6F,\
U+0D85..U+0DC6,U+1900..U+1938,U+1946..U+194F,U+A800..U+A805,\
U+A807..U+A822,U+0386->U+03B1,U+03AC->U+03B1,U+0388->U+03B5,\
U+03AD->U+03B5,U+0389->U+03B7,U+03AE->U+03B7,U+038A->U+03B9,\
U+0390->U+03B9,U+03AA->U+03B9,U+03AF->U+03B9,U+03CA->U+03B9,\
U+038C->U+03BF,U+03CC->U+03BF,U+038E->U+03C5,U+03AB->U+03C5,\
U+03B0->U+03C5,U+03CB->U+03C5,U+03CD->U+03C5,U+038F->U+03C9,\
U+03CE->U+03C9,U+03C2->U+03C3,U+0391..U+03A1->U+03B1..U+03C1,\ 
U+03A3..U+03A9->U+03C3..U+03C9,U+03B1..U+03C1,U+03C3..U+03C9,\
U+0E01..U+0E2E,U+0E30..U+0E3A,U+0E40..U+0E45,U+0E47,U+0E50..U+0E59,\
U+A000..U+A48F,U+4E00..U+9FBF,U+3400..U+4DBF,U+20000..U+2A6DF,\
U+F900..U+FAFF,U+2F800..U+2FA1F,U+2E80..U+2EFF,U+2F00..U+2FDF,\
U+3100..U+312F,U+31A0..U+31BF,U+3040..U+309F,U+30A0..U+30FF,\
U+31F0..U+31FF,U+AC00..U+D7AF,U+1100..U+11FF,U+3130..U+318F,\
U+A000..U+A48F,U+A490..U+A4CF

ngram_len       = 1
ngram_chars     = U+4E00..U+9FBF,U+3400..U+4DBF,U+20000..U+2A6DF,\
U+F900..U+FAFF,U+2F800..U+2FA1F,U+2E80..U+2EFF,U+2F00..U+2FDF,\
U+3100..U+312F,U+31A0..U+31BF,U+3040..U+309F,U+30A0..U+30FF,\
U+31F0..U+31FF,U+AC00..U+D7AF,U+1100..U+11FF,U+3130..U+318F,\
U+A000..U+A48F,U+A490..U+A4CF

html_strip      = 0
html_index_attrs    = img=alt,title; a=title;
html_remove_elements  = style, script
}
index dist_txt
{
type            = distributed
local           = s_txt
agent           = localhost:3313:remote1
agent           = localhost:3314:remote2,remote3
agent_connect_timeout  = 1000
agent_query_timeout    = 3000
}



#------------------------------------------------------------------------
index s_comment
{
source          = s_comment
path            = /var/data/s_comment
docinfo         = extern
mlock           = 0
morphology      = none
min_word_len    = 1
charset_type    = utf-8
charset_table   = U+FF10..U+FF19->0..9,0..9,U+FF41..U+FF5A->a..z,\
U+FF21..U+FF3A->a..z,A..Z->a..z,a..z,U+0149,U+017F,U+0138,U+00DF,\
U+00FF,U+00C0..U+00D6->U+00E0..U+00F6,U+00E0..U+00F6,\
U+00D8..U+00DE->U+00F8..U+00FE,U+00F8..U+00FE,U+0100->U+0101,\
U+0101,U+0102->U+0103,U+0103,U+0104->U+0105,U+0105,U+0106->U+0107,\
U+0107,U+0108->U+0109,U+0109,U+010A->U+010B,U+010B,U+010C->U+010D,\
U+010D,U+010E->U+010F,U+010F,U+0110->U+0111,U+0111,U+0112->U+0113,\
U+0113,U+0114->U+0115,U+0115,U+0116->U+0117,U+0117,U+0118->U+0119,\
U+0119,U+011A->U+011B,U+011B,U+011C->U+011D,U+011D,U+011E->U+011F,\
U+011F,U+0130->U+0131,U+0131,U+0132->U+0133,U+0133,U+0134->U+0135,\
U+0135,U+0136->U+0137,U+0137,U+0139->U+013A,U+013A,U+013B->U+013C,\
U+013C,U+013D->U+013E,U+013E,U+013F->U+0140,U+0140,U+0141->U+0142,\
U+0142,U+0143->U+0144,U+0144,U+0145->U+0146,U+0146,U+0147->U+0148,\
U+0148,U+014A->U+014B,U+014B,U+014C->U+014D,U+014D,U+014E->U+014F,\
U+014F,U+0150->U+0151,U+0151,U+0152->U+0153,U+0153,U+0154->U+0155,\
U+0155,U+0156->U+0157,U+0157,U+0158->U+0159,U+0159,U+015A->U+015B,\
U+015B,U+015C->U+015D,U+015D,U+015E->U+015F,U+015F,U+0160->U+0161,\
U+0161,U+0162->U+0163,U+0163,U+0164->U+0165,U+0165,U+0166->U+0167,\
U+0167,U+0168->U+0169,U+0169,U+016A->U+016B,U+016B,U+016C->U+016D,\
U+016D,U+016E->U+016F,U+016F,U+0170->U+0171,U+0171,U+0172->U+0173,\
U+0173,U+0174->U+0175,U+0175,U+0176->U+0177,U+0177,U+0178->U+00FF,\
U+00FF,U+0179->U+017A,U+017A,U+017B->U+017C,U+017C,U+017D->U+017E,\
U+017E,U+0410..U+042F->U+0430..U+044F,U+0430..U+044F,U+05D0..U+05EA,\
U+0531..U+0556->U+0561..U+0586,U+0561..U+0587,U+0621..U+063A,U+01B9,\
U+01BF,U+0640..U+064A,U+0660..U+0669,U+066E,U+066F,U+0671..U+06D3,\
U+06F0..U+06FF,U+0904..U+0939,U+0958..U+095F,U+0960..U+0963,\
U+0966..U+096F,U+097B..U+097F,U+0985..U+09B9,U+09CE,U+09DC..U+09E3,\
U+09E6..U+09EF,U+0A05..U+0A39,U+0A59..U+0A5E,U+0A66..U+0A6F,\
U+0A85..U+0AB9,U+0AE0..U+0AE3,U+0AE6..U+0AEF,U+0B05..U+0B39,\
U+0B5C..U+0B61,U+0B66..U+0B6F,U+0B71,U+0B85..U+0BB9,U+0BE6..U+0BF2,\
U+0C05..U+0C39,U+0C66..U+0C6F,U+0C85..U+0CB9,U+0CDE..U+0CE3,\
U+0CE6..U+0CEF,U+0D05..U+0D39,U+0D60,U+0D61,U+0D66..U+0D6F,\
U+0D85..U+0DC6,U+1900..U+1938,U+1946..U+194F,U+A800..U+A805,\
U+A807..U+A822,U+0386->U+03B1,U+03AC->U+03B1,U+0388->U+03B5,\
U+03AD->U+03B5,U+0389->U+03B7,U+03AE->U+03B7,U+038A->U+03B9,\
U+0390->U+03B9,U+03AA->U+03B9,U+03AF->U+03B9,U+03CA->U+03B9,\
U+038C->U+03BF,U+03CC->U+03BF,U+038E->U+03C5,U+03AB->U+03C5,\
U+03B0->U+03C5,U+03CB->U+03C5,U+03CD->U+03C5,U+038F->U+03C9,\
U+03CE->U+03C9,U+03C2->U+03C3,U+0391..U+03A1->U+03B1..U+03C1,\ 
U+03A3..U+03A9->U+03C3..U+03C9,U+03B1..U+03C1,U+03C3..U+03C9,\
U+0E01..U+0E2E,U+0E30..U+0E3A,U+0E40..U+0E45,U+0E47,U+0E50..U+0E59,\
U+A000..U+A48F,U+4E00..U+9FBF,U+3400..U+4DBF,U+20000..U+2A6DF,\
U+F900..U+FAFF,U+2F800..U+2FA1F,U+2E80..U+2EFF,U+2F00..U+2FDF,\
U+3100..U+312F,U+31A0..U+31BF,U+3040..U+309F,U+30A0..U+30FF,\
U+31F0..U+31FF,U+AC00..U+D7AF,U+1100..U+11FF,U+3130..U+318F,\
U+A000..U+A48F,U+A490..U+A4CF

ngram_len       = 1
ngram_chars     = U+4E00..U+9FBF,U+3400..U+4DBF,U+20000..U+2A6DF,\
U+F900..U+FAFF,U+2F800..U+2FA1F,U+2E80..U+2EFF,U+2F00..U+2FDF,\
U+3100..U+312F,U+31A0..U+31BF,U+3040..U+309F,U+30A0..U+30FF,\
U+31F0..U+31FF,U+AC00..U+D7AF,U+1100..U+11FF,U+3130..U+318F,\
U+A000..U+A48F,U+A490..U+A4CF

html_strip      = 0
html_index_attrs    = img=alt,title; a=title;
html_remove_elements  = style, script
}
index dist_comment
{
type            = distributed
local           = s_comment
agent           = localhost:3313:remote1
agent           = localhost:3314:remote2,remote3
agent_connect_timeout  = 1000
agent_query_timeout    = 3000
}



###############################################################
### indexer settings
###############################################################

indexer
{
# 索引過程中記憶體的使用限制,預設為 32M。
mem_limit       = 64M

# 每秒最大 I/O 操作次數,用於限制 I/O 操作。預設為0(無限制)。
#max_iops       = 40

# 最大單次允許的 I/O 操作大小,以 bytes 為單位,用於I/O節流。預設為0(不限制)。
#max_iosize     = 1048576
}



###############################################################
### searchd settings
###############################################################

searchd
{
# 監聽來源 IP,預設為0.0.0.0(即允許所有 IP 連結)。
#address        = 127.0.0.1


# searchd 的 TCP port。預設為 3312。
port            = 3312


# log 的紀錄文件位址,全部 searchd 運行時事件會被記錄在這個日誌文件中。 
log             = /var/log/sphinx/searchd.log


# 查詢日誌文件名,預設為空(不記錄查詢日誌)。
# 全部搜索查詢會被記錄在此文件中。
query_log       = /var/log/sphinx/query.log


# 最大的查詢請求時間,單位是秒。預設是5秒。
# searchd 將強制關閉在此時間內未能成功發出查詢的客戶端連接。 
read_timeout    = 5


# 並行執行的搜索的數目。預設為0(無限制)。
max_children    = 30


# searchd 進程 ID 文件名。必選項。
pid_file        = /var/log/sphinx/searchd.pid


# 守護進程在記憶體中為每個索引所保持並返回給客戶端的匹配數目的最大值。預設為1000
max_matches     = 1000


# 防止 searchd 輪換在需要預取大量數據的索引時停止響應。預設為1(啟用無縫(seamless)輪換)
seamless_rotate = 1


# 是否在啟動時強制重新打開所有索引文件。預設為0(不重新打開)。
preopen_indexes = 0


# 索引輪換成功之後,是否刪除以.old為擴展名的索引拷貝。預設為1(刪除這些索引拷貝)。
unlink_old      = 1
}

# --eof--



啟動搜尋引擎

開始建立索引及啟動搜尋引擎
# 為所有 sphinx.conf 中設定的資料來源建立索引
/usr/local/bin/indexer --config /usr/local/etc/sphinx.conf --all

# 以 sphinx.conf 中的設定啟動搜尋引擎
/usr/local/bin/searchd --config /usr/local/etc/sphinx.conf


動態更新索引的方法
# 更新所有資料來源
/usr/local/bin/indexer --rotate --config /usr/local/etc/sphinx.conf --all 

# 更新特定的資料來源(s_tit),並且不顯示任何訊息
/usr/local/bin/indexer --quiet --rotate --config /usr/local/etc/sphinx.conf s_tit



主要程式及運作方式

Sphinx 主要有以下部分:
  • indexer: 建立索引庫的程序,在查詢前必須先建立索引庫。
  • search: 提供 console 下的搜尋介面,可用於測試用。
  • searchd: 主要的 service 程序,以 port 為連接介面去對索引庫取得資料。
  • SphinxAPI: 連結 searchd 的客戶端 API,目前支援的 script 語言有(PHP, Python, Perl, Ruby)。
  • SphinxSE: 透過 MySQL 連結 searchd 的資料表引擎。

Sphinx 架構圖


命令列參數說明

indexer
格式:indexer [OPTIONS] [indexname1 [indexname2 [...]]]
  • --config <file> (-c <file>精簡指令) 指定 sphinx.conf 的位址,預設為 /usr/local/etc/sphinx.conf
  • --all 為所有資料來源建立索引,在利用 cron 定期更新索引庫時,可使用此參數更新所有資料來源的索引
  • --rotate 動態更新來源索引,可用在 searchd 仍處於啟動的狀態。
  • --quiet 告訴 indexer 不輸出任何訊息,除非有一個錯誤。在 cron 上使用時非常方便。
  • --noprogress 不顯示進展的細節訊息。而在最後輸出的細節訊息(如文件索引,索引的速度等等)
  • --merge <dst-index> <src-index> 合併 <src-index> 到 <dst-index>,<dst-index>會保存有合併後的結果,<src-index> 不會被修改。
  • --merge-dst-range <attr> <min> <max>合併時過濾 <dst-index> 僅保留 <attr> 值在 <min> 和 <max> (包含)的記錄.


searchd
格式:searchd [OPTIONS]
  • --help (-h 精簡指令) 列出所有的參數說明。
  • --config <file> (-c <file> 精簡指令) 指定 sphinx.conf 的位址,預設為 /usr/local/etc/sphinx.conf
  • --stop 停止 searchd 引擎的運作
  • --console 強制使用 console 介面(windows)
  • --port portnumber (-p 精簡指令) 強制變更 searchd 連結端口(port)的位址
  • --index <index> (-i 精簡指令) 指定唯一的搜尋索引,主要用於測試用。


search
格式:search [OPTIONS] word1 [word2 [word3 [...]]]

一般選項:
  • --config <file>(-c <file> 精簡指令) 讓 search 使用特定的 conf 檔作為配置,就像前面 indexer。
  • --index <index>(-i <index> 精簡指令) 讓 search 限制搜尋的索引檔,預設會嘗試搜尋所有 conf 檔中列出的索引。
  • --stdin tells search 讓 search 接受查詢從標準輸入,而不是命令行。這可用在測試目的上,即可以透過管線輸入或 script。


設置匹配選項:
  • --any (-a 精簡指令) 匹配所有的搜尋關鍵字。
  • --phrase (-p 精簡指令) 短語匹配。
  • --boolean (-b 精簡指令) 布林表達式匹配。
  • --ext (-e 精簡指令) 查詢匹配一個Sphinx內部查詢語言表達式。
  • --ext2 (-e2 精簡指令) 查詢匹配一個Sphinx內部查詢語言表達式。
  • --filter <attr> <v> (-f <attr> <v> 精簡指令) 過慮條件,可用在過慮 conf 中以 attr 標註的欄位,(--filter InsertDate 2009)過慮出建立日期為 2009 的資料


處理結果輸出選項:
  • --limit <count>(-l count 精簡指令) 輸出 row 的數量(預設為20)。
  • --offset <count>(-o <count>精簡指令) 輸出 row 的起始(預設為0)。
  • --group <attr>(-g <attr>精簡指令) specifies that results should be grouped together based on the attribute specified. Like the GROUP BY clause in SQL, it will combine all results where the attribute given matches, and returns a set of results where each returned result is the best from each group. Unless otherwise specified, this will be the best match on relevance.
  • --groupsort <expr>(-gs <expr>精簡指令) instructs that when results are grouped with -group, the expression given in <expr>shall determine the order of the groups. Note, this does not specify which is the best item within the group, only the order in which the groups themselves shall be returned.
  • --sortby <clause>(-s <clause>精簡指令) specifies that results should be sorted in the order listed in <clause>. This allows you to specify the order you wish results to be presented in, ordering by different columns. For example, you could say --sortby "@weight DESC entrytime DESC" to sort entries first by weight (or relevance) and where two or more entries have the same weight, to then sort by the time with the highest time (newest) first. You will usually need to put the items in quotes (--sortby "@weight DESC") or use commas (--sortby @weight,DESC) to avoid the items being treated separately. Additionally, like the regular sorting modes, if --group (grouping) is being used, this will state how to establish the best match within each group.
  • --sortexpr expr (-S expr 精簡指令) specifies that the search results should be presented in an order determined by an arithmetic expression, stated in expr. For example: --sortexpr "@weight + ( user_karma + ln(pageviews) )*0.1" (again noting that this will have to be quoted to avoid the shell dealing with the asterisk). Extended sort mode is discussed in more detail under the SPH_SORT_EXTENDED entry under the Sorting modes chapter of the manual.
  • --sort=date 指定以降幕排序的欄位,必須在 conf 中以 attr 標註的欄位。
  • --rsort=date 指定以升幕排序的欄位,必須在 conf 中以 attr 標註的欄位。



摘要使用

Sphinx 的 API 提供摘要產生的功能
在下載的安裝包中可以找到這份範例
<?php

//
// $Id: test2.php 910 2007-11-16 11:43:46Z shodan $
//

require ( "sphinxapi.php" );

$docs = array
(
"this is my test text to be highlighted, and for the sake ".
"of the testing we need to pump its length somewhat",
"another test text to be highlighted, below limit",
"test number three, without phrase match",
"final test, not only without phrase match, but also above ".
"limit and with swapped phrase text test as well",
);
$words = "test text";
$index = "test1";
$opts = array
(
"before_match"    => "<b>",
"after_match"    => "</b>",
"chunk_separator"  => " ... ",
"limit"        => 60,
"around"      => 3,
);

foreach ( array(0,1) as $exact )
{
$opts["exact_phrase"] = $exact;
print "exact_phrase=$exact\n";

$cl = new SphinxClient ();
$res = $cl->BuildExcerpts ( $docs, $index, $words, $opts );
if ( !$res )
{
die ( "ERROR: " . $cl->GetLastError() . ".\n" );
} else
{
$n = 0;
foreach ( $res as $entry )
{
$n++;
print "n=$n, res=$entry\n";
}
print "\n";
}
}

//
// $Id: test2.php 910 2007-11-16 11:43:46Z shodan $
//

?>



搜尋的匹配模式

匹配模式SPH_MATCH_ALL
匹配所有
SPH_MATCH_ANY
匹配任意
SPH_MATCH_PHRASE
短语匹配
SPH_MATCH_EXTENDED
内部查询
觀察必須包含前後順序,所有 word 都要包含。word 符合前後順序權重高,中文會拆字查詢。必須包前後順序,而且是有序比對(排除標點符號)。無特定前後順序,但有符合前後順序的權重比較高。
權重特性Max match_word lemgth(match_word1 lemgth)^2+
(match_word2 lemgth)^2
match_word lemgthBM25
最高權重值{順序完全批配的word數}{所有 word 數}^2{word數}
沒有較小的權重,此為唯一權重值。
?
word 對結果的影響用所有的 word 進行查詢,只要有一個 word 不符合就不撈出來。符合其中一個word。完全符合前後順序與所有word。符合全數word。
查詢時 word 的先後可以不同。正確的順序權重較高。必要。順序不同不會出現在結果裡。前後順序影響權重。
適合用途適合不會打錯的查詢,word 很少的查詢。多 word 的查詢。完全精準查詢。適合不會打錯的查詢,word 很少的查詢。
特性word 越多,查詢越少。有一個 word 沒有就找不到了。word 越多,資料越多。幾乎等於 SQL like。word 越多,資料越少,權重值會拉開,且權重值是根據所有可能結果之間的差異做權重。



建立 SphinxSE 表

SphinxSE 的使用方式是利用一個虛擬的資料表去與 searchd 作連結
這個表本身不會儲存任何資料,也不能新增資料
利用這個資料表可以作任何 SQL SELECT 的操作(JOIN ...)
-- @ sphinx_interface(Sphinx搜尋連接介面)
CREATE TABLE `sphinx_interface` (
-- 前三個為必要欄位,
-- 欄位屬性順序必須為 INTEGER,INTEGER,VARCHAR
-- 分別標記為(id),匹配權重(weight),查詢(query)
-- 不限定欄位名稱
-- 同時 id 及 query 必須建立索引。
`id` INT NOT NULL                COMMENT '搜尋結果的 Id',
`weight` INT NOT NULL            COMMENT '搜尋結果的權重',
`query` VARCHAR(3072) NOT NULL   COMMENT '搜尋的查詢條件',

-- 額外欄位,需與 sphinx.conf 中 sql_attr 設定的欄位一致,
-- 欄位屬性必須為 INTEGER,VARCHAR 或 TIMESTAMP,
-- 此處的設定可作後續的排序或過濾用。
`insertdate` VARCHAR(3072) NOT NULL  COMMENT '日期', 
`commentnum` INTEGER                 COMMENT '回應總數',
INDEX(id),
INDEX(query)
)ENGINE=SPHINX 
-- CONNECTION 的格式為 sphinx://HOST:PORT/INDEXNAME
-- 建議先不加 INDEXNAME,等在查詢時在決定 index
CONNECTION="sphinx://localhost:3312/" 
COMMENT='Sphinx搜尋連接介面';



SphinxSE 的使用方式

  • query 查詢文本

  • mode 匹配模式.必須是 "all", "any", "phrase", "boolean" 或 "extended",預設為“all”

  • sort 匹配項排序模式必須是“relevance”, “attr_desc”, “attr_asc”, “time_segments”或“extended”之一。除了“relevance”模式,其他模式中還必須在一個冒號後附上屬性名(或“extended”模式中的排序子句)。
    ... WHERE query='test;sort=attr_asc:group_id';
    ... WHERE query='test;sort=extended:@weight desc, group_id asc';

  • offset 結果集中的偏移量,預設是0。

  • limit 從結果集中獲取的匹配項數目,預設為20。

  • index 待搜索的索引:
    ... WHERE query='test;index=test1;';
    ... WHERE query='test;index=test1,test2,test3;';

  • minid , maxid 匹配文檔ID的最小值和最大值

  • weights 逗號分隔的列表,指定Sphinx全文數據字段的權值
    ... WHERE query='test;weights=1,2,3;';

  • filter , !filter 逗號分隔的列表,指定一個屬性名和一系列可匹配的屬性值:
    -- 僅包括群組 1, 5 和 19
    ... WHERE query='test;filter=group_id,1,5,19;';
    
    -- 排除的群組 3 和 11
    ... WHERE query='test;!filter=group_id,3,11;';

  • range , !range 逗號分隔的列表,指定一個屬性名和該屬性可匹配的最小值和最大值:
    -- 僅包括群組 3 至 7 之間 的 group_id
    ... WHERE query='test;range=group_id,3,7;';
    
    -- 排除的群組 5 至 25 之間的 group_id
    ... WHERE query='test;!range=group_id,5,25;';

  • maxmatches 此查詢最大匹配的數量:
    ... WHERE query='test;maxmatches=2000;';

  • groupby 分組(group-by)函數和屬性:
    ... WHERE query='test;groupby=day:published_ts;';
    ... WHERE query='test;groupby=attr:group_id;';

  • groupsort 分組(group-by)排序子句
    ... WHERE query='test;groupsort=@count desc;';

  • indexweights 逗號分隔的列表,指定一系列索引名和搜索時這些索引對應的權值
    ... WHERE query='test;indexweights=idx_exact,2,idx_stemmed,1;';

參考來源

Sphinx 0.9.8.1 reference manual
Coreseek 全文檢索服務器2.0 (Sphinx 0.9.8) 參考手冊
Sphinx速成指南

Sphinx 自由開放原始碼全文搜尋引擎
ubuntu下Mysql+sphinx+中文分词安装配置
Mysql+sphinx+中文分词简介(ubuntu)
用 PHP 构建自定义搜索引擎