Commit bed990ad authored by Victor Emanouilov's avatar Victor Emanouilov
Browse files

[FIX] manticore: fatal error when more than 256 fields defined in admin; make...

[FIX] manticore: fatal error when more than 256 fields defined in admin; make sure title,contents or whatever is defined in default search fields setting is always indexed as full-text in manticore; add fulltext wildcard search settings and refactor query builder to use a single match subquery supported by manticore
parent fe3fa315
Pipeline #648597969 failed with stages
in 51 minutes and 42 seconds
......@@ -199,6 +199,8 @@ class Search_Indexer
// TODO: calm this down once integration is stable
echo $e->getMessage() . "\n";
var_dump($e->getContext());
} catch (Search_Manticore_FatalException $e) {
throw new Exception($e->getMessage());
} catch (Exception $e) {
$msg = tr(
'Indexing failed while processing "%0" (type %1) with the error "%2"',
......
<?php
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
class Search_Manticore_FatalException extends Search_Manticore_Exception
{
}
......@@ -128,6 +128,7 @@ class Search_Manticore_Index implements Search_Index_Interface, Search_Index_Que
file_put_contents($stopwords_file, implode("\n", $prefs['unified_stopwords']));
$settings = [
'min_infix_len' => 2,
'stopwords' => $stopwords_file,
'morphology' => $prefs['unified_manticore_morphology'] ?? '',
// TODO: see what other options to support https://manual.manticoresearch.com/Creating_an_index/Local_indexes/Plain_and_real-time_index_settings#Natural-language-processing-specific-settings
......@@ -147,11 +148,21 @@ class Search_Manticore_Index implements Search_Index_Interface, Search_Index_Que
}
if (! empty($prefs['unified_manticore_always_index'])) {
$data = explode(',', $prefs['unified_manticore_always_index']);
$data = preg_split('/\s*,\s*/', $prefs['unified_manticore_always_index']);
} else {
$data = [];
}
if (! empty($prefs['unified_default_content'])) {
$data = array_merge($data, $prefs['unified_default_content']);
$data = array_unique($data);
}
if (count($data) > 256) {
$data = null;
throw new Search_Manticore_FatalException(tr('Fatal Manticore error: you have defined more than 256 fields to be indexed as full-text. Please edit search setting "unified_manticore_always_index" to decrease the number of fields.'));
}
if (! $this->indexer) {
return $data;
}
......
......@@ -20,7 +20,7 @@ use Manticoresearch\Query;
class Search_Manticore_QueryDecorator extends Search_Manticore_Decorator
{
protected $factory;
protected $currentOp;
protected $matches;
protected $documentReader;
public function __construct(\Manticoresearch\Search $search, Search_Manticore_Index $index)
......@@ -30,7 +30,6 @@ class Search_Manticore_QueryDecorator extends Search_Manticore_Decorator
parent::__construct($search, $index);
$this->factory = new Search_Manticore_TypeFactory();
$this->currentOp = $prefs['unified_search_default_operator'] == 1 ? \Manticoresearch\Search::FILTER_AND : \Manticoresearch\Search::FILTER_OR;
$this->documentReader = function ($type, $object) {
return null;
};
......@@ -44,7 +43,13 @@ class Search_Manticore_QueryDecorator extends Search_Manticore_Decorator
public function decorate(Search_Expr_Interface $expr)
{
$this->matches = [];
$q = $expr->traverse($this);
foreach ($this->matches as $method => $subqs) {
foreach ($subqs as $subq) {
$q->$method($subq);
}
}
$this->search->search($q);
}
......@@ -90,8 +95,12 @@ class Search_Manticore_QueryDecorator extends Search_Manticore_Decorator
foreach ($childNodes as $child) {
$subq = $child->traverse($callback);
if ($subq) {
$q->$method($subq);
$isEmpty = false;
if ($subq instanceof Query\MatchQuery || $subq instanceof Query\MatchPhrase) {
$this->matches[$method][] = $subq;
} else {
$q->$method($subq);
$isEmpty = false;
}
}
}
if ($isEmpty) {
......@@ -154,10 +163,14 @@ class Search_Manticore_QueryDecorator extends Search_Manticore_Decorator
$mapping = $this->index ? $this->index->getFieldMapping($node->getField()) : new stdClass();
if ($mapping && in_array('indexed', $mapping['options'])) {
if ($prefs['unified_search_default_operator'] == 1) {
return new Query\MatchQuery($this->getTerm($node), $this->getNodeField($node));
$phrase = $this->getTerm($node);
if ($prefs['unified_search_default_operator'] != 1) {
$phrase = preg_replace('/\s+/', ' | ', $phrase);
}
if ($node->getType() == 'identifier') {
return new Query\MatchPhrase($phrase, $this->getNodeField($node));
} else {
return new Query\MatchPhrase($this->getTerm($node), $this->getNodeField($node));
return new Query\MatchQuery($phrase, $this->getNodeField($node));
}
} elseif (isset($mapping['types']) && in_array('json', $mapping['types']) && $node->getType() == 'multivalue') {
return new Query\In($this->getNodeField($node), json_decode($this->getTerm($node)));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment