我使用ZF2 Search Lucene搜索网站上的产品。我需要使用用户的输入文本搜索产品,并通过几个参数过滤结果,如类别和类型的id。但是问题是用户的输入会在所有字段中搜索,而我只需要在Name和Description字段中搜索。
下面是向索引中添加产品的代码:
$index = Lucene::create('./data/index');
$products = $this->getEntityManager()->getRepository('ApplicationEntityProduct')->findAll();
foreach ($products as $product) {
echo "Adding ".$product->getName(). " to indexn";
$doc = new LuceneDocument();
$doc->addField(LuceneDocumentField::keyword('type', 'product'));
$doc->addField(LuceneDocumentField::keyword('product_id', (string)$product->getId()));
$doc->addField(LuceneDocumentField::keyword('category_id', (string)$product->getCategory()->getId()));
$fieldName = LuceneDocumentField::text('product_name', $product->getName());
$fieldName->boost = 2.0; // Field weight
$doc->addField($fieldName);
$fieldDescription = LuceneDocumentField::unStored('product_description', $product->getDescription());
$fieldDescription->boost = 1.0; // Field weight
$doc->addField($fieldDescription);
$index->addDocument($doc);
}
$index->commit();
搜索代码:
$userQueryString = 'search input query string';
$userQuery = LuceneSearchQueryParser::parse($userQueryString);
// how to limit userQuery to search only in specific fields?
$typeTerm = new LuceneIndexTerm('product', 'type');
$typeQuery = new LuceneSearchQueryTerm($typeTerm);
$categoryTerm = new LuceneIndexTerm(5, 'category_id');
$categoryQuery = new LuceneSearchQueryTerm($categoryTerm);
$query = new LuceneSearchQueryBoolean();
$query->addSubquery($typeQuery, true /* required */);
$query->addSubquery($categoryQuery, true /* required */);
$query->addSubquery($userQuery, true /* required */);
$index = Lucene::open('./data/index');
$hits = $index->find($query);
foreach ($hits as $hit) {
echo "Type: ".$hit->type."n";
echo "Id: ".$hit->product_id."n";
echo "Name: ".$hit->product_name."n";
echo "Category: ".$hit->category_id."n";
echo "n";
}
文档表明
与Java Lucene的第一个也是最重要的区别是默认情况下通过搜索所有字段。
如果你想用LuceneSearchQueryParser::parse()
的方法,你可以这样制备$userQueryString
:
$userQueryString = 'name:search input query string description:search input query string';
也可以这样使用ZendSearchLuceneSearchQueryMultiTerm::addTerm()
方法:
...
$userQuery = new ZendSearchLuceneSearchQueryMultiTerm();
$userQuery->addTerm(new ZendSearchLuceneIndexTerm($userQueryString, 'name'));
$userQuery->addTerm(new ZendSearchLuceneIndexTerm($userQueryString, 'description'));
...
$query->addSubquery($userQuery, true /* required */);