Zend Lucene поиск только в указанных полях с фильтром

Я использую ZF2 Search Lucene для поиска товаров на сайте. Мне нужно искать продукты, используя вводимый пользователем текст, и фильтровать результат по нескольким параметрам, таким как Категория и Тип по идентификатору. Но суть в том, что вводимые пользователем данные ищутся во всех полях, и мне нужно искать только в полях Имя и Описание.

Вот код для добавления товаров в индекс:

    $index = Lucene::create('./data/index');

    $products = $this->getEntityManager()->getRepository('Application\Entity\Product')->findAll();

    foreach ($products as $product) {
        echo "Adding ".$product->getName(). " to index\n";
        $doc = new LuceneDocument();

        $doc->addField(LuceneDocument\Field::keyword('type', 'product'));
        $doc->addField(LuceneDocument\Field::keyword('product_id', (string)$product->getId()));
        $doc->addField(LuceneDocument\Field::keyword('category_id', (string)$product->getCategory()->getId()));

        $fieldName = LuceneDocument\Field::text('product_name', $product->getName());
        $fieldName->boost = 2.0; // Field weight
        $doc->addField($fieldName); 

        $fieldDescription = LuceneDocument\Field::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 = LuceneSearch\QueryParser::parse($userQueryString);
    // how to limit userQuery to search only in specific fields?

    $typeTerm  = new LuceneIndex\Term('product', 'type');
    $typeQuery = new LuceneSearch\Query\Term($typeTerm);

    $categoryTerm  = new LuceneIndex\Term(5, 'category_id');
    $categoryQuery = new LuceneSearch\Query\Term($categoryTerm);

    $query = new LuceneSearch\Query\Boolean();
    $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";
    }

1 ответ

Документация стоит, что

Первое и самое существенное отличие от Java Lucene заключается в том, что термины ищутся во всех полях по умолчанию.

Если вы хотите использовать LuceneSearch\QueryParser::parse() метод, вы можете подготовить $userQueryString как это:

$userQueryString = 'name:search input query string description:search input query string';

Также вы можете использовать Zend\Search\Lucene\Search\Query\MultiTerm::addTerm() метод как это:

...
$userQuery = new Zend\Search\Lucene\Search\Query\MultiTerm();
$userQuery->addTerm(new Zend\Search\Lucene\Index\Term($userQueryString, 'name'));
$userQuery->addTerm(new Zend\Search\Lucene\Index\Term($userQueryString, 'description'));
...
$query->addSubquery($userQuery, true /* required */);
Другие вопросы по тегам