2. 布尔查询
布尔查询允许使用下列特殊操作符:
显式的与(AND)操作符
hello & world
或(OR)操作符
hello | world
非(NOT)操作符
hello -world
hello !world
分组(grouping)
( hello world )
以下是一个使用了如上全部操作符的例子:
布尔查询示例
( cat -dog ) | ( cat -mouse)
与(AND)操作符为默认操作,所以“hello world”其实就是“hello & world”
或(OR)操作符的优先级高于与操作符,因此“lookingfor cat | dog | mouse”意思是”looking for (
cat | dog | mouse )” 而不是 “(looking for cat) | dog | mouse”
像“-dog”这种查询不能被执行,因为它差不多包括索引所有文档。这既有技术上的原因,
也有性能上的原因。从技术上说,Sphinx并不总是保持一个全部文档ID的列表。性能方面,
当文档集非常大的时候(即10-100M个文档),对这种执行查询可能需要很长的时间。
3. 扩展查询
在扩展查询模式中可以使用如下特殊操作符:
或(OR)操作符
hello | world
非(NOT)操作符
hello -world
hello !world
字段(field)搜索符:
@title hello @body world
词组搜索符
“hello world”
近似搜索符
“hello world”~10
阀值匹配符
“the world is a wonderful place”/3
下例使用了上述大多数操作符:
扩展查询示例
“hello world” @title “example program”~5 @body python -(php|perl)
与(AND)操作为默认操作,因此“hello world”意思是“hello”和“world”必须同时存在文档才
能匹配。
或(OR)操作符的优先级要高于与操作符,因此”looking for cat | dog | mouse” 意思
是”looking for ( cat | dog | mouse )” 而不是”(looking for cat) | dog | mouse”;
近似距离以词为单位,随词数变化而变化,并应用于引号中的全部词。举个例子,”cat dog
mouse”~5 这个查询的意思是必须有一个少于8个词的词串,它要包含全部的三个词,也就
是说”CAT aaa bbb ccc DOG eee fff MOUSE” 这个文档不会匹配这个查询,因为这个词串正好
是8个词。
阀值匹配符引入了一种模糊匹配。它允许至少含有某个阈值数量个匹配词的文档通过。上述
例子(”the world is a wonderful place”/3)会匹配含有指定的六个词中的至少三个的那些文档。
类似如下查询中嵌套的括号
aaa | ( bbb ccc | ( ddd eee ) )
目前还是不允许的,但是这会在今后得以改进。
取否(也就是非(NOT)操作符)只允许用在最外一层且不能在括号(也就是分组)里。这
个特性不会改变,因为支持嵌套的非操作会大大提高词组相关度计算实现的复杂性。
4. 权值计算
采用何种权值计算函数(目前)取决于查询的模式。
There are these major parts which are used in the weighting functions:
权值计算函数进行如下两部分主要部分:
1. 词组评分
2. 统计学评分
词组评分根据文档和查询的最长公共子串(LCS,longest common subsequence)的长度进行。
因此如果文档对查询词组有一个精确匹配(即文档直接包含该词组),那么它的词组评分就
取得了可能的最大值,也就是查询中词的个数。
统计学评分基于经典的BM25函数,该函数仅考虑词频。如果某词在整个数据库中很少见
(即文档集上的低频词)或者在某个特定文档中被经常提及(即特定文档上的高频词),那
么它就得到一个较高的权重。最终的BM25权值是一个0到1之间的浮点数。
在所有模式中,数据字段的词组评分是LCS乘以用户指定的数据字段权值。数据字段权值
是整数,默认为1,且字段的权值必须不小于1。
在SPH_MATCH_BOOLEAN模式中,不做任何权重估计,每一个匹配项的权重都是1。
在SPH_MATCH_ALL和SPH_MATCH_PHRASE模式中,最终的权值是词组评分的加权和。
在SPH_MATCH_ANY模式中,于前面述两模式的基本思想类似,只是每个数据字段的权重
都再加上一个匹配词数目。在那之前,带权的词组相关度被额外乘以一个足够大的数,以便
确保任何一个有较大词组评分的数据字段都会使整个匹配的相关度较高,即使该数据字段的
权重比较低。
在SPH_MATCH_EXTENDED模式中,最终的权值是带权的词组评分和BM25权重的和,再
乘以1000并四舍五入到整数。
这个行为将会被修改,以便使MATCH_ALL和MATCH_ANY这两个模式也能使用BM25算
法。这将使词组评分相同的搜索结果片断得到改进,这在只有一个词的查询中尤其有用。
关键的思想(对于除布尔模式以外的全部模式中)是子词组的匹配越好则评分越高,精确匹
配(匹配整个词组)评分最高。作者的经验是,这种基于词组相似性的评分方法可以提供比
任何单纯的统计模型(比如其他搜索引擎中广泛使用的BM25)明显更高的搜索质量。
1.先在mysql中插入一个计数表和两个索引表
CREATE TABLE sph_counter(
counter_id INTEGER PRIMARY KEY NOT NULL,
max_doc_id INTEGER NOT NULL
);
//主索引使用(确认之前是否已经建立过该表,如果已经建立,这里就不需要重新建了)
CREATE TABLE `sphinx` (
`id` int(11) NOT NULL,
`weight` int(11) NOT NULL,
`query` varchar(255) NOT NULL,
`CATALOGID` INT NOT NULL,
`EDITUSERID` INT NOT NULL,
`HITS` INT NULL,
`ADDTIME` INT NOT NULL, KEY
`Query` (`Query`)
) ENGINE=SPHINX DEFAULT CHARSET=utf8 CONNECTION=’sphinx://localhost:3312/test1′
//增量索引使用
CREATE TABLE `sphinx1` (
`id` int(11) NOT NULL,
`weight` int(11) NOT NULL,
`query` varchar(255) NOT NULL,
`CATALOGID` INT NOT NULL,
`EDITUSERID` INT NOT NULL,
`HITS` INT NULL,
`ADDTIME` INT NOT NULL, KEY
`Query` (`Query`)
)ENGINE=SPHINX DEFAULT CHARSET=utf8 CONNECTION=’sphinx://localhost:3312/ test1stemmed ‘
2.修改sphinx.conf
source src1
{
sql_query_pre = SET NAMES utf8
sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents
sql_query = SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content FROM documents \
WHERE id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
... //其他可以默认
}
// 注意:sql_query_pre的个数需和src1对应,否则可能搜索不出相应结果
source src1throttled : src1
{
sql_ranged_throttle = 100
sql_query_pre = SET NAMES utf8
sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_pre =
sql_query = SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content FROM documents \
WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
}
make时错误
../libtool: line 466: CDPATH: command not found
../libtool: line 1144: func_opt_split: command not found
libtool: Version mismatch error. This is libtool 2.2.6, but the
libtool: definition of this LT_INIT comes from an older release.
libtool: You should recreate aclocal.m4 with macros from libtool 2.2.6
libtool: and run autoconf again.
make[1]: *** [conf_to_src] 错误 63
make[1]: Leaving directory `/home/andychu/lemp2/mysql-5.1.26-rc/strings’
make: *** [all-recursive] 错误 1
Mysql>
输入
show engines;
+————+———+———————————————————–+————–+—-+————+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+————+———+———————————————————–+————–+—-+————+
| CSV | YES | CSV storage engine | NO | NO | NO |
| SPHINX | YES | Sphinx storage engine 0.9.8 | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
+————+———+———————————————————–+————–+—-+————+
5 rows in set (0.00 sec)
此时我们可以看到已经包含sphinxSE 引擎
3.安装sphinx
cd /root/lemp/sphinx-0.9.8-rc2
./configure –prefix=/usr/local/sphinx –with-mysql=/opt/mysql \
–with-mysql-includes=/opt/mysql/include/mysql –with-mysql-libs=/opt/mysql/lib/mysql \
–with-mmseg-includes=/usr/local/mmseg/include –with-mmseg-libs=/usr/local/mmseg/lib –with-mmseg
make
/root/sphinx/sphinx-0.9.8-rc2/src/tokenizer_zhcn.cpp:34: undefined reference to `libiconv_close’
collect2: ld returned 1 exit status
官网解决办法:
In the meantime I’ve change the configuration file and set
#define USE_LIBICONV 0 in line 8179.
修改configure 文件把 #define USE_LIBICONV 0 最后的数值由1改为0
重新编译。
vi configure
输入/define USE_LIBICONV 找到目标行
按i键后将1改成0,按esc,输入:wq保存退出
make
make install
编译时报如下的错误
/usr/local/include/mmseg/freelist.h:22: error: ‘strlen’ was not declared in this scope
vi /usr/local/include/mmseg/freelist.h
或者这个地址
vi /usr/local/mmseg/include/mmseg/freelist.h
加上
#include
再次编译就不会报错了。
复制一份sphinx的配置
cd /usr/local/sphinx/etc
cp sphinx.conf.dist sphinx.conf
4.配置sphinx
修改/usr/local/sphinx/etc/sphinx.conf
type = mysql
# some straightforward parameters for SQL source types
sql_host = localhost
sql_user = root
sql_pass =
sql_db = test
sql_port = 3306 # optional, default is 3306
2 通过search工具查询
/usr/local/sphinx/bin/search –config /usr/local/sphinx/etc/sphinx.conf test
3 通过php的接口查询 详见sphinxapi.php.
三、在mysql中的使用SphinxSE方式调用Sphinx
1.在mysql中的使用SphinxSE方式调用Sphinx
首先建立一张索引专用表:
CREATE TABLE `sphinx` (
`id` int(11) NOT NULL,
`weight` int(11) NOT NULL,
`query` varchar(255) NOT NULL,
`CATALOGID` INT NOT NULL,
`EDITUSERID` INT NOT NULL,
`HITS` INT NULL,
`ADDTIME` INT NOT NULL, KEY
`Query` (`Query`)
) ENGINE=SPHINX DEFAULT CHARSET=utf8 CONNECTION=’sphinx://localhost:3312/test1′
test1:索引的名称,可以在sphinx.conf中查找到
建立完索引专用表后,我们就可以在mysql中使用它了,例如,在mysql中输入
SELECT doc. * FROM documents doc JOIN sphinx ON ( doc.id = sphinx.id ) WHERE query = ‘doc;mode= any’
创建/etc/init.d/sphinx脚本
#!/bin/sh
# sphinx: Startup script for Sphinx search
#
# chkconfig: 345 86 14
# description: This is a daemon for high performance full text \
# search of MySQL and PostgreSQL databases. \
# See http://www.sphinxsearch.com/ for more info.
#
# processname: searchd
# pidfile: $sphinxlocation/var/log/searchd.pid
# Source function library.
. /etc/rc.d/init.d/functions
$searchd –stop
#killproc -p $pidfile $servicename -TERM
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/$servicename
rm -f $pidfile
fi
}
# See how we were called.
case “$1″ in
start)
start
;;
stop)
stop
;;
status)
status $processname
RETVAL=$?
;;
restart)
stop
sleep 3
start
;;
condrestart)
if [ -f /var/lock/subsys/$servicename ]; then
stop
sleep 3
start
fi
;;
*)
echo $”Usage: $0 {start|stop|status|restart|condrestart}”
;;
esac
exit $RETVAL
近期评论