full-text search 3

This commit is contained in:
yuri
2018-06-21 12:41:10 +03:00
parent d83530bbf6
commit 87518f33a9
7 changed files with 86 additions and 12 deletions

View File

@@ -150,7 +150,7 @@ class Base
} else {
$orderPart = 'DESC';
}
$result['orderBy'] = [[$sortBy . 'Country', $orderPart], [$sortBy . 'City', $orderPart], [$sortBy . 'Street', $orderPart]];
$result['orderBy'] = [[$sortBy . 'Country', $orderPart], [$sortBy . 'City', $orderPart], [$sortBy . '_eet', $orderPart]];
return;
} else if ($type === 'enum') {
$list = $this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'fields', $sortBy, 'options']);
@@ -1514,6 +1514,10 @@ class Base
return null;
}
if ($this->getConfig()->get('fullTextSearchDisabled')) {
return null;
}
$result = null;
$fieldList = $this->getTextFilterFieldList();
@@ -1522,8 +1526,15 @@ class Base
$textFilter = str_replace('%', '', $textFilter);
}
$fullTextSearchColumnList = $this->getEntityManager()->getOrmMetadata()->get($this->getEntityType(), ['fullTextSearchColumnList']);
$useFullTextSearch = false;
if ($this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'collection', 'fullTextSearch'])) {
if (
$this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'collection', 'fullTextSearch'])
&&
!empty($fullTextSearchColumnList)
) {
$fullTextSearchMinLength = $this->getConfig()->get('fullTextSearchMinLength', self::MIN_LENGTH_FOR_FULL_TEXT_SEARCH);
if (!$fullTextSearchMinLength) {
$fullTextSearchMinLength = 0;
@@ -1549,6 +1560,10 @@ class Base
}
}
if (empty($fullTextSearchColumnList)) {
$useFullTextSearch = false;
}
if ($useFullTextSearch) {
if (
mb_strpos($textFilter, ' ') === false
@@ -1564,15 +1579,18 @@ class Base
$function = 'MATCH_BOOLEAN';
}
$fullTextSearchFieldSanitizedList = [];
foreach ($fullTextSearchFieldList as $i => $field) {
$fullTextSearchFieldSanitizedList[$i] = $this->getEntityManager()->getQuery()->sanitize($field);
$fullTextSearchColumnSanitizedList = [];
$query = $this->getEntityManager()->getQuery();
foreach ($fullTextSearchColumnList as $i => $field) {
$fullTextSearchColumnSanitizedList[$i] = $query->sanitize($query->toDb($field));
}
$where = $function . ':' . implode(',', $fullTextSearchFieldSanitizedList) . ':' . $textFilter;
$where = $function . ':' . implode(',', $fullTextSearchColumnSanitizedList) . ':' . $textFilter;
$result = [
'where' => $where,
'fieldList' => $fullTextSearchFieldList
'fieldList' => $fullTextSearchFieldList,
'columnList' => $fullTextSearchColumnList
];
}
@@ -1593,11 +1611,12 @@ class Base
$forceFullTextSearch = false;
$useFullTextSearch = !empty($result['forceFullTextSearch']);
$useFullTextSearch = !empty($result['useFullTextSearch']);
if (mb_strpos($textFilter, 'ft:') === 0) {
$textFilter = mb_substr($textFilter, 3);
$useFullTextSearch = true;
$forceFullTextSearch = true;
}
$skipWidlcards = false;

View File

@@ -186,6 +186,8 @@ class Converter
$ormMetadata = Util::merge($ormMetadata, $convertedLinks);
$this->applyFullTextSearch($ormMetadata, $entityName);
if (!empty($entityMetadata['collection']) && is_array($entityMetadata['collection'])) {
$collectionDefs = $entityMetadata['collection'];
$ormMetadata[$entityName]['collection'] = array();
@@ -467,4 +469,46 @@ class Converter
return $values;
}
protected function applyFullTextSearch(&$ormMetadata, $entityType)
{
if (!$this->getMetadata()->get(['entityDefs', $entityType, 'collection', 'fullTextSearch'])) return;
$fieldList = $this->getMetadata()->get(['entityDefs', $entityType, 'collection', 'textFilterFields'], ['name']);
$fullTextSearchColumnList = [];
foreach ($fieldList as $field) {
$defs = $this->getMetadata()->get(['entityDefs', $entityType, 'fields', $field], []);
if (empty($defs['type'])) continue;
$fieldType = $defs['type'];
if (!empty($defs['notStorable'])) continue;
if (!$this->getMetadata()->get(['fields', $fieldType, 'fullTextSearch'])) continue;
$partList = $this->getMetadata()->get(['fields', $fieldType, 'fullTextSearchColumnList']);
if ($partList) {
if ($this->getMetadata()->get(['fields', $fieldType, 'naming']) === 'prefix') {
foreach ($partList as $part) {
$fullTextSearchColumnList[] = $part . ucfirst($field);
}
} else {
foreach ($partList as $part) {
$fullTextSearchColumnList[] = $field . ucfirst($part);
}
}
} else {
$fullTextSearchColumnList[] = $field;
}
}
if (!empty($fullTextSearchColumnList)) {
$ormMetadata[$entityType]['fullTextSearchColumnList'] = $fullTextSearchColumnList;
if (!array_key_exists('indexes', $ormMetadata[$entityType])) {
$ormMetadata[$entityType]['indexes'] = [];
}
$ormMetadata[$entityType]['indexes']['system_fullTextSearch'] = [
'columns' => $fullTextSearchColumnList,
'flags' => ['fulltext']
];
}
}
}

View File

@@ -206,6 +206,11 @@ class EntityManager
return $this->metadata;
}
public function getOrmMetadata()
{
return $this->getMetadata();
}
public function getPDO()
{
if (empty($this->pdo)) {

View File

@@ -70,6 +70,6 @@
"linkAudited": "Creating related record and linking with existing record will be logged in Stream.",
"linkMultipleField": "Link Multiple field provides a handy way to edit relations. Don't use it if you can have a large number of related records.",
"entityType": "Base Plus - has Activities, History and Tasks panels.\n\nEvent - available in Calendar and Activities panel.",
"fullTextSearch": "Running rebuild required."
"fullTextSearch": "Running rebuild is required."
}
}

View File

@@ -433,7 +433,8 @@
"collection": {
"sortBy": "dateSent",
"asc": false,
"textFilterFields": ["name", "bodyPlain", "body"]
"textFilterFields": ["name", "bodyPlain", "body"],
"fullTextSearch": true
},
"indexes": {
"dateSent": {

View File

@@ -29,5 +29,10 @@
"notCreatable":true,
"filter":true,
"skipOrmDefs": true,
"personalData": true
"personalData": true,
"fullTextSearch": true,
"fullTextSearchColumnList": [
"first",
"last"
]
}

View File

@@ -103,7 +103,7 @@ class GlobalSearch extends \Espo\Core\Services\Base
}
$selectManager->manageAccess($params);
$params['forceFullTextSearch'] = true;
$params['useFullTextSearch'] = true;
$selectManager->applyTextFilter($query, $params);
$sql = $this->getEntityManager()->getQuery()->createSelectQuery($entityType, $params);