如何利用 lucene score机制来实现 关键字 竞价排名

[flash=336,280]http://img.alimama.cn/bm/wrappler_swf/2009-11-26/2042702_0af5658d088e285c4ac474cd20865090_336x280.swf?v=1259240549[/flash]lucene内置的排序方式是按照一定算法的score来排列,document的boost能影响文档的权重,但与关键字并无法实现直接的关系。

比如说对文档一加了100的boost。那么无论搜什么关键字,这个文档都有可能出现在最前面。这个结果并不是我们期望的效果。

有一个办法可以实现按照关键字的排序。

例如:关键字 玻璃

在这个购买了关键字的公司的相关信息document创建lucene索引时。需要人为的添加一个字段.这个数据与用户发付费有关。而与真实信息无关。

Field field=new Field("玻璃","玻璃 玻璃 玻璃")
field name 为什么这样写,在下面搜索的是就知道了。
document.add(field);

根据lucene score 算法。重复2次的score最高。不过这个score的分值与ANALYZER有关系,不同的ANALYZER重复次数不一样。根据lucene score的算法明显和重复次数不是线性的。

这里是一些测试数据

当关键字是n个字长。ANALYZER=WhitespaceAnalyzer
按照score分值,从高到低 关键字的重复频率应该为 2 5 17 8 11 6 16 20 10 15 19 7 18 14 3 9 4 13 12
如果用WhitespaceAnalyzer,这个频率是固定。不管n个字是什么.
都是这样排列。





import java.io.IOException;

import junit.framework.TestCase;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;

import com.linkmd.search.constants.XmlConstants;

/**
* <b>按照购买的关键字来排序</b>
* @since 2009-5-7
* @version 1.0
*/
public class KeywordSearchTest extends TestCase {

private static final Analyzer ANALYZER = new WhitespaceAnalyzer();
private static final String[] PAY_KEY ={ "芯片","大脑","大菠萝","家乐福"};
private static final int comNumber=20;
private static final int[][] result=new int[2][comNumber];

/**
* @throws Exception
*/
@SuppressWarnings( { "static-access", "deprecation" })
public void testSearch2() throws Exception {

for(int y=0,len=PAY_KEY.length;y<len;y++){
System.out.println("PAY_KEY.length:"+PAY_KEY[y].length());
test(y);
System.out.println();
}
}

private void test(int y) throws CorruptIndexException,
LockObtainFailedException, IOException, ParseException {
Directory ram = new RAMDirectory();
IndexWriter writer = new IndexWriter(ram, ANALYZER, true,
MaxFieldLength.UNLIMITED);

for (int i = 0; i <comNumber; i++) {
Document doc = new Document();
Field field = new Field("companyName", "公司" + i,
Field.Store.YES, Field.Index.NOT_ANALYZED);
doc.add(field);

/**
* 付费字段 关键字设置
*/
StringBuilder key = new StringBuilder();
String finalKey = "";
if (i % 1 == 0) {
for (int x = 0; x < i; x++) {
key.append(this.PAY_KEY[y]);
key.append(" ");
}
finalKey = key.toString();
}
Field payField = new Field("pay_key_word", finalKey,
Field.Store.YES, Field.Index.ANALYZED);
doc.add(payField);
writer.addDocument(doc);
// System.out.println(doc);
}
writer.close();

IndexSearcher searcher = new IndexSearcher(ram);
QueryParser p = new QueryParser("pay_key_word", ANALYZER);
Query q = p.parse(this.PAY_KEY[y]);
Hits hits = searcher.search(q);
System.out.println("total:"+hits.length());
for (int i = 0, size = hits.length(); i < size; i++) {
Document doc = hits.doc(i);
int length = doc.getField("pay_key_word").toString().split(" ").length;
System.out.print(length+" ");
}
searcher.close();
}


}





现在索引已经建好了。搜索的时候。如果某一个用户输入了玻璃。应该先去数据库查一下,是否这个关键字已经被购买。如果购买了,那么在查询的时刻,我们需要在query的构造上加入
"玻璃":"玻璃"。然后sort数组加上 "玻璃",然后是普通的字段,比如 info 字段的 玻璃 这样查询的顺序就应该按照我们的意思来排序了。

我需要先试试效果。应该可行。

不过其实要实现 关键字 还有很多办法。当然直接结合数据库也可以实现。


[url=http://www.571g.com/info/19.html]社区购物 彤瑶诗佳西兴店正品名牌全场四折[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值