neoslive / hybridsearch
在此处添加描述
Requires
- dev-master
- 1.1.44
- 1.1.43
- 1.1.42
- 1.1.41
- 1.1.40
- 1.1.39
- 1.1.38
- 1.1.37
- 1.1.36
- 1.1.35
- 1.1.34
- 1.1.33
- 1.1.32
- 1.1.31
- 1.1.30
- 1.1.29
- 1.1.28
- 1.1.27
- 1.1.26
- 1.1.25
- 1.1.24
- 1.1.23
- 1.1.22
- 1.1.21
- 1.1.20
- 1.1.19
- 1.1.18
- 1.1.17
- 1.1.16
- 1.1.15
- 1.1.14
- 1.1.13
- 1.1.12
- 1.1.11
- 1.1.10
- 1.1.9
- 1.1.8
- 1.1.7
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.26
- 1.0.25
- 1.0.24
- 1.0.23
- 1.0.22
- 1.0.21
- 1.0.20
- 1.0.19
- 1.0.18
- 1.0.17
- 1.0.16
- 1.0.15
- 1.0.14
- 1.0.13
- 1.0.12
- 1.0.11
- 1.0.10
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
This package is not auto-updated.
Last update: 2024-09-28 20:14:34 UTC
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 个并发搜索请求,通常需要首先积累数千万的日活跃用户。
演示/案例
- https://www.phlu.ch(Neos)
实现
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>