neoslive/hybridsearch

此包最新版本(1.1.44)没有可用的许可信息。

在此处添加描述

安装: 613

依赖项: 1

建议者: 0

安全: 0

星标: 8

关注者: 2

分支: 0

公开问题: 0

语言:JavaScript

类型:neos-package


README

HybridSearch 是一个基于智能索引机制的强大实时搜索引擎,由 Google Firebase(noSQL)提供支持,并使用 JavaScript/AngularJS 编写。Hybrid 代表了流式搜索结果的创新方式。每次搜索请求都会提供小的、预先选择的数据块,然后在客户端进行计算以生成搜索结果。每当源应用程序(Neos CMS、Magento 等)的数据发生变化时,HybridSearch 会更新搜索索引并实时更新当前搜索结果——这就是为什么我们称之为实时搜索引擎。该搜索引擎由 Michael Egli 在 2016 年发明,是一种免费开源软件。特别感谢 Oliver Nightingale(lunr.js)和 Wei Song(elasticlunr.js)。

特性

  • 边打字边搜索(自动完成和自动更正在后台完成)。
  • 实时绑定(搜索索引和结果视图)。
  • 分析 Google Analytics 报告以实现更好的语义(可选)。
  • 从渲染和结构化数据创建搜索索引,而不仅仅是原始数据。
  • 索引时无需配置。
  • 提供 JavaScript 框架以创建出色的用户体验.
  • 最小但强大的配置(相关性提升、过滤、唯一性、分面等)
  • 高性能,搜索时无需服务器端利用,索引时 CPU 使用率非常低。
  • 支持高达 100,000 个并发搜索请求。要达到 100,000 个并发搜索请求,通常需要首先积累数千万的日活跃用户。

演示/案例

实现

HybridSearch 配有 Neos CMS 的默认集成。其他实现非常容易。即将推出 Magento 的默认实现。

使用 Neos 安装

后端

最小配置

composer require neoslive/hybridsearch

免费 创建一个新的 Firebase 项目。然后您需要一个数据库令牌。打开 Firebase 项目设置并创建新的数据库密钥/令牌(请参阅服务帐户 > 数据库密钥)。

将以下内容添加到您的 flow Settings.yaml(最小配置)

Neoslive:
  Hybridsearch:
    Realtime: true 
    Firebase:
      endpoint: 'https://** your firebase project name**.firebaseio.com/'
      token: '** your firebase token **'
    Filter:
      GrantParentNodeTypeFilter: '[instanceof TYPO3.Neos:Document]'
      ParentNodeTypeFilter: '[instanceof TYPO3.Neos:Node]'
      NodeTypeFilter: '[instanceof TYPO3.Neos:Content]'

最佳配置

Settings.yaml 的示例

Neoslive:
  Hybridsearch:
    Realtime: true
    Firebase:
      endpoint: 'https://** your firebase project name**.firebaseio.com/'
      token: '** your firebase token **'
    Filter:
      GrantParentNodeTypeFilter: '[instanceof TYPO3.Neos:Document]'
      ParentNodeTypeFilter: '[instanceof TYPO3.Neos:Node]'
      NodeTypeFilter: '[instanceof Neoslive.Hybridsearch:Content]'
    TypoScriptPaths:
      page:
        Vendor.Package: neosliveHybridsearch
      breadcrumb:
        Vendor.Package: neosliveHybridsearchBreadcrumb

如果您使用最佳配置,则需要以下类似设置。

TypoScript(root.ts)

neosliveHybridsearch = TYPO3.TypoScript:Collection {
    collection = ${q(node)}
    itemName = 'node'
    itemRenderer = TYPO3.Neos:ContentCase
}

neosliveHybridsearchBreadcrumb = TYPO3.TypoScript:Collection {
    collection = ${q(node)}
    itemName = 'node'
    itemRenderer = Breadcrumb
}

NodeTypes.yaml

# Make your contact node searchable
'Vendor.Package:Contact:
  superTypes:
    'Neoslive.Hybridsearch:Content': TRUE
    

索引您的数据

运行 flow 命令以初始化索引您的 Neos 网站

php ./flow hybridsearch:createfullindex

为了更好的语义,您应该使用最佳配置,并且不要索引所有节点类型。索引器将每个节点渲染为独立的前端视图,而不仅仅是简单的原始数据,因此最初需要一些时间。但结果是神奇的。

如果您设置了 "Realtime: true",则所有后续更改都将作为智能的后台异步作业自动执行,而不会在 Neos 后端编辑时对性能产生影响。

建议定期执行完整的索引创建。只需创建一个像这样的cronjob:

1 1 * * 1 FLOW_CONTEXT=Production php -d memory_limit=8096M /home/www-data/flow hybridsearch:createfullindex >/dev/null 2>&1

因此,在您的索引正在创建时,您不应该等待并执行前端集成。

前端

将以下javascript文件添加到您的布局/模板中。

<script src="{f:uri.resource(path: 'Vendor/angular/angular.min.js', package: 'Neoslive.Hybridsearch')}"></script>
<script src="{f:uri.resource(path: 'Vendor/firebase/firebase.js', package: 'Neoslive.Hybridsearch')}"></script>
<script src="{f:uri.resource(path: 'Vendor/angularfire/dist/angularfire.min.js', package: 'Neoslive.Hybridsearch')}"></script>
<script src="{f:uri.resource(path: 'Vendor/angular-sanitize/angular-sanitize.min.js', package: 'Neoslive.Hybridsearch')}"></script>
<script src="{f:uri.resource(path: 'Vendor/elasticlunr.js/elasticlunr.min.js', package: 'Neoslive.Hybridsearch')}"></script>
<script src="{f:uri.resource(path: 'hybridsearch.js', package: 'Neoslive.Hybridsearch')}"></script>

创建一个Angular控制器。

.controller('searchCtrl', ['$scope', '$hybridsearch', '$hybridsearchObject', '$hybridsearchResultsObject', function ($scope, $hybridsearch, $hybridsearchObject, $hybridsearchResultsObject) {

// initialize scope vars
$scope.result = new $hybridsearchResultsObject();
$scope.query = '';

// initialize HybridSearch
var search = new $hybridsearchObject(
                new $hybridsearch(
                    'https://** your firebase project name**.firebaseio.com',
                    'live',
                    '** dimensionHash **',
                    '** nodename of the site'
        ));
        
// set search settings and run HybridSearch
search
.setQuery('query',$scope)
.$bind('result', $scope)
.run();     

}]);


创建一个HTML搜索页面。

<div data-ng-controller="searchCtrl">
    
    <h1>Search:</h1> 
    <input type="text" data-ng-model="query" placeholder="Search for...">
    
    <h1>Results {{result.count()}}</h1>
    
     <div data-ng-repeat="node in result.getNodes()">
         <h2>{{node.getProperty('title')}}</h2>
         <p>{{node.getPreview()}}</p>
     </div>
  
</div>

HybridSearch自有JavaScript框架

HybridSearch提供了一种javascript框架,用于创建出色的用户体验。在几分钟内创建强大的搜索、列表、标签筛选器等,而且一切都与实时索引无缝连接,无需编写一行代码。

初始化

var hybridSearch = new $Hybridsearch(
 'https://<DATABASE_NAME>.firebaseio.com',
 'live',
 'fb11fdde869d0a8fcfe00a2fd35c031d',
 'site-root-node-name'
));
var mySearch = new $HybridsearchObject(hybridSearch);

$HybridsearchObject(定义搜索请求)

这是主要的请求对象,其中所有定义搜索请求的方法都被调用。

配置方法

这些方法影响搜索结果的行为。

setNodeTypeLabels

对于每个resulting nodeType,搜索引擎会根据nodeType创建一个组名。因此,您可以轻松创建标签化的搜索结果等。使用setNodeTypeLabels方法,您可以将多个nodeType组合并为一个。

参数
返回

{HybridsearchObject} 搜索对象

示例
  • setNodeTypeLabels({'vendor-package-contact': 'Persons'},{'vendor-package-customers': 'Persons'}) 将联系人和客户合并为名为“Persons”的一个组。

setPropertiesBoost

调整每个nodeType属性的关联度评分计算。更高的值意味着匹配属性的关联度评分更高。

参数
返回

{HybridsearchObject} 搜索对象

示例
  • setPropertiesBoost({'vendor-package-contact-name': 50},{'vendor-package-contact-lastname': 50}) 在lastname中匹配的查询具有较高的评分

setParentNodeTypeBoostFactor

调整每个节点及其父节点类型的关联度评分计算。给定的boost值是应用于每个节点关联度评分的因子。

参数
返回

{HybridsearchObject} 搜索对象

示例
  • setParentNodeTypeBoostFactor({'typo3-neos-contentcollection1': 1.8,'typo3-neos-contentcollection2': 1.5}) contentcollection1中的节点比contentcollection2中的节点评分更高

过滤方法

这些方法限制搜索结果。

setQuery

为搜索设置一个查询。如果提供范围,则将参数视为对scopes变量的引用,并自动监视任何更改。如果未定义参数范围,则搜索字符串本身。

参数
返回

{HybridsearchObject} 搜索对象

setNodeType

设置节点类型(例如'wrapper-package-contact')。如果提供范围,则将参数视为对scopes变量的引用,并自动监视任何更改。如果未定义参数范围,则搜索字符串本身。节点类型与Neos节点类型等效,但所有特殊字符都被替换为'-',并且所有内容都转换为小写。

参数
返回

{HybridsearchObject} 搜索对象

addPropertyFilter

添加一个属性过滤器,限制搜索结果。如果提供范围,则将参数视为对scopes变量的引用,并自动监视任何更改。如果未定义参数范围,则搜索字符串本身。

参数
返回

{HybridsearchObject} 搜索对象

示例
var persons = [
{'name':'michael','lastname': 'moor', primaryAdress: {'email': 'foo@bar.com'},secondaryAdress: {'email': 'foo@bar.com'}
{'name':'peter','lastname': 'moor', primaryAdress: {'email': 'peter@foo.com'},secondaryAdress: {'email': 'peter@bar.com'}
];
  • addPropertyFilter('persons.name',['michael','peter']) 查找名为'michael'或'peter'的人员
  • addPropertyFilter('persons.name',{'michael': true,'peter': false}) 查找名为'michael'但不是'peter'的人员
  • addPropertyFilter('persons.*.email','foo@bar.com') 查找在主要或次要地址中具有电子邮件'foo@bar.com'的人员

setNodePath

设置节点路径(或uri段),这是搜索的入口点。如果提供范围,则将参数视为对scopes变量的引用,并自动监视任何更改。如果未定义参数范围,则搜索字符串本身。节点类型与Neos节点类型等效,但所有特殊字符都被替换为'-',并且所有内容都转换为小写。

参数
返回

{HybridsearchObject} 搜索对象

示例
  • setNodePath('/company/about/') 仅获取位于uri路径'/company/about/'下的搜索结果

预处理方法

这些方法在应用搜索过滤器之前被调用。

addNodesByIdentifier

通过指定的节点标识符(uuid)将节点添加到本地搜索索引。如果没有进一步的限制(过滤器),则添加的节点将被添加到搜索结果中。

参数
返回

{HybridsearchObject} 搜索对象

示例
  • addNodesByIdentifier(['64021902-b7d9-11e6-80f5-76304dec7eb7','57978ed3-6e41-48ce-8421-22d80beacef0']) 将节点添加到本地搜索索引。

后处理方法

在计算搜索结果之后调用这些方法。

setOrderBy

设置结果的排序。您可以在模板视图中排序结果,但那时您不能使用限制/分页方法。排序是按nodeType或nodeTypeLabel配置的。排序不能是DESC,因为它是一个复杂搜索算法的内部行为。

参数
返回

{HybridsearchObject} 搜索对象

示例
  • setOrderBy({'vendor-package-contact': ['name','lastname']}) 按名称和姓氏对联系人节点进行排序
  • setOrderBy({'*': 'title'}) 按标题对所有其他节点进行排序

setGroupedBy

按给定的标识符对结果进行分组。使用此groupedBy函数,您可以从搜索结果中过滤掉重复项。groupedBy按nodeType或nodeTypeLabel配置。

参数
返回

{HybridsearchObject} 搜索对象

示例
  • setGroupedBy({'vendor-package-contact': ['name','lastname']}) 按名称和姓氏对联系人节点进行分组。因此,只有具有不同全名的个人才应用于搜索结果。
  • setGroupedBy({'*': 'title'}) 按标题对所有其他节点进行分组

运行时方法

这些方法在初始化时最多调用一次。

$watch

监视{HybridsearchResultsObject}的任何变化。

返回

{HybridsearchObject} 搜索对象

示例
  • $watch(function(data) {console.log(data);}) 函数参数'data'包含当前的搜索结果。

$bind

将{HybridsearchResultsObject}绑定到给定的作用域变量。

参数
返回

{HybridsearchObject} 搜索对象

示例
  • $bind('result',$scope) 搜索结果自动应用于angular作用域变量'result',您可以在控制器中使用它。

$HybridsearchResultsObject (定义搜索结果)

这是主要的结果对象,其中所有方法都被调用来呈现搜索结果。

运行时方法

isLoading

检查搜索是否正在进行。当当前搜索完成时返回false。

返回

{布尔值}搜索是否完成

示例
  • $scope.status = isLoading() ? '请等待' : countAll()+'个结果找到'

计数器方法

计数器方法提供有关当前搜索结果的统计信息。

count

获取当前结果中节点(不包括turbo节点)的数量

返回

{整数}不包括turbo节点的节点数

示例
  • <div>结果 {{result.count()}}</div> 其中result是绑定到HybridsearchResultsObject的作用域变量(见$bind)

countAll

获取当前结果中节点(包括turbo节点)的数量

返回

{整数}包括turbo节点的节点数

countTurboNodes

获取当前结果中turbo节点的数量

返回

{整数}turbo节点的数量

countByNodeType

按节点类型获取当前结果中的节点数量

参数
返回

{整数}节点数

countByNodeTypeLabel

按节点类型标签获取当前结果中的节点数量

参数
返回

{整数}节点数

getDistinctCount

获取当前搜索结果的唯一值(唯一)数量。

参数
返回

{整数}不同值的数量

获取器方法

获取器方法提供结果作为集合{HybridsearchResultsNode}。

getNodes

获取结果集合(不包括turbo节点)

参数
返回

{数组} HybridsearchResultsNode集合

示例
  • <ul><li data-ng-repeat="node in result.getNodes()">{{node.getProperty('title')}}</li></ul> 其中result是绑定到HybridsearchResultsObject的作用域变量(见$bind)

getTurboNodes

获取结果集合(仅turbo节点)

参数
返回

{数组} HybridsearchResultsNode集合

getNodesByNodeType

按节点类型获取结果集合

参数
返回

{数组} HybridsearchResultsNode集合

getNodesByNodeTypeLabel

按节点类型标签获取结果集合

参数
返回

{数组} HybridsearchResultsNode集合

getDistinct

获取给定属性的唯一值

参数
返回

{Object.value} 值 {Object.count} 包含此值的节点数量。

getGrouped

从当前搜索结果获取所有节点,形成一个分组对象。

返回

{HybridsearchResultsGroupObject} 结果分组

示例
<ul>
 <li data-ng-repeat="group in result.getGrouped().getItems()">
  <h1>{{group.getLabel()}} ({{group.count()}})</h1>
    <ul>
      <li data-ng-repeat="node in group.getNodes()">
        <h2>{{node.getProperty('title')}} </h2>
        <div data-ng-bind-html="node.getBreadcrumb()"></div>
      </li>
    </ul>
 </li>
</ul>

其中结果是一个作用域变量,与 HybridsearchResultsObject 绑定(见 $bind)

$HybridsearchResultsGroupObject(定义一组结果)

此对象代表一个分组结果。

count

获取分组对象中的项目数量

返回

{Integer} 项目数量

getItems

获取分组项目作为数组

返回

{array} 包含 {HybridsearchResultsDataObject} 的集合

$HybridsearchResultsDataObject(定义一组结果)

此对象代表一组结果项目。

count

获取此组中的项目数量

返回

{Integer} 项目数量

getLabel

获取分组标签

返回

{String} 分组标签

getNodes

获取结果集合(不包括turbo节点)

参数
返回

{数组} HybridsearchResultsNode集合

getProperty

通过给定属性获取组中第一个节点的值。这对于获取分组对象的值很有用。

参数
返回

{Mixed} 属性值

$HybridsearchResultsNode(定义单个结果项/节点)

此对象代表单个结果项。

获取器方法

getter 方法提供有关项目的信息。

getNodeType

获取节点类型。

返回

{String} 节点类型

getScore

获取项目的相关性分数。

返回

{integer} 相关性分数(最高值是最高相关性)

isTurboNode

检查是否是 turbo 节点或普通节点。

返回

{boolean} 如果是 turbo 节点则为 true,默认为普通节点

getBreadcrumb

获取面包屑作为 HTML 代码(如果是文档节点)。

返回

{String} HTML

getUrl

获取 URL(如果是文档节点)。

返回

{String} url

getPreview

获取节点的渲染预览。

参数
返回

{String} 预览内容

getSortingIndex

获取节点的排序索引。

返回

{Integer} 排序索引值

getProperty

通过给定属性获取值。

参数
返回

{Mixed} 属性值

示例
  • {{node.getProperty('name')}} 返回混合节点类型的名称
  • {{node.getProperty('vendor-package-contact-name')}} 仅返回节点类型 vendor-package-contact 的名称
  • {{node.getProperty('primaryAdress.email')}} 返回主要电子邮件
  • {{node.getProperty('*.email')}} 返回所有电子邮件地址

getDocumentNode

获取最近的文档节点。

返回

{HybridsearchResultsNode} 包含面包屑和 URL 的 HybridsearchResultsNode

示例
<ul>
  <li data-ng-repeat="node in result.getNodes()">
    <h2>{{node.getDocumentNode().getProperty('title')}} </h2>
    <p>Name: {node.getProperty('name')}}</p>
    <p>Lastname: {node.getProperty('lastname')}}</p>
   </li>
</ul>