基于 ElasticSearch 的搜索索引 - 您的数据保留在 default 中
使用 ElasticSearch 进行搜索,但将数据保留在 MySQL/Postgres(您的默认数据库配置)中。这种行为在每次保存后将一个“索引”字符串保存到 ElasticSearch,搜索将针对该字符串进行,但您的数据与之前完全相同。
Elastic Search 索引
https://github.com/zeroasterisk/CakePHP-ElasticSearchIndex
此插件允许您轻松创建基于`ElasticSearch`_ 的搜索索引,并具有各种`Lucene`_ 功能。(它为 GitHub 提供支持)
通过此插件,您可以将模型保留在您自己的普通(默认)数据源中。所有保存、查找、联接和回调... 都是正常的。
但是,当您附加此行为时,您将获得额外的回调,这些回调会收集您要用作搜索索引的数据... 它会通过自身数据源将这些数据存储到 ElasticSearch 中,` index`,如(上述)Elastic 插件中设置的那样。
最终,您既能拥有蛋糕又能吃掉它。
- 您的模型和数据源保持不变,并按预期工作。**所有数据仍然保留在它一直存在的位置**您仍然可以进行联接**非搜索条件仍然可以在普通字段上工作
- ElasticSearch / Lucene 的搜索功能可供您使用**每个记录的索引字符串是数据的文本的自定义副本**它也对 ElasticSearch 上的其他用途可用
现在您可以按以下方式搜索
- 词语:foo
- 多词语:foobar
- 部分词语:fo*
- 前缀部分词语:*oo
- 短语:“foobar”
- 模糊词语:~bars(以` ~` 开头)
- … 等等 ...(有建议吗?)
注意:它运行良好,但如果您想帮助改进它,我们可以使用更多 ElasticSearch 特殊功能。
安装
将此插件安装到位
`
git submodule add https://github.com/zeroasterisk/CakePHP-ElasticSearchIndexapp/Plugin/ElasticSearchIndex
#or
git clone https://github.com/zeroasterisk/CakePHP-ElasticSearchIndexapp/Plugin/ElasticSearchIndex
`
并安装`Icing`_ 插件
`
gitsubmoduleaddhttps://github.com/AudiologyHoldings/Icingapp/Plugin/Icing
#or
gitclonehttps://github.com/AudiologyHoldings/Icingapp/Plugin/Icing
`
在` app/Config/bootstrap.php` 中加载插件
`
CakePlugin::load('Icing');
CakePlugin::load('ElasticSearchIndex');
`
将默认` ElasticSearchRequest` 配置复制到您的应用程序中,并根据您的设置进行编辑。
`
cpapp/Plugin/Icing/Config/elastic_search_request.php.defaultapp/Config/elastic_search_request.php
`
请注意,有一个` default` 配置和一个` test` 配置,它将覆盖` default` 配置... 但只有当您的测试设置了以下 Configure 变量时
`
Configure::write('inUnitTest',true);
`
现在,将插件设置到您想要搜索/索引的任何模型中
在您的` Model` 中添加此行为
`
public$actsAs=array(
'ElasticSearchIndex.ElasticSearchIndexable'=>array(),
);
`
以下是行为配置选项,以及默认值
`
public$actsAs=array(
'ElasticSearchIndex.ElasticSearchIndexable'=>array(
//urltotheelasticsearchindexforthismodel/table
'url'=>null,
//extraconfigforElasticSearchRequest(parsedfromURL)
'index'=>null,
//extraconfigforElasticSearchRequest(parsedfromURL,ordefaultedto$Model->useTable)
'table'=>null,
//limitthesearchresultstothismanyresults
'limit'=>200,
//detailsneededtolinktoModel
'foreignKey'=>false,//primaryKeytosaveagainst
//dowebuildtheindexaftersave?(yes...)
'rebuildOnUpdate'=>true,
//whenwebuildtheindex,considerthesefields(ignonredifcustommethodonmodel)
//eg:array('title','name','email','city','state','country'),
//orforall(text/varchar)fields:'*'
'fields'=>'*',
//whenwebuildtheindex,dowefinddatafirst?(iffalse,weonlyhavethedatawhichwassaved)
'queryAfterSave'=>true,
//optionalconfigforHttpSocket(bettertoconfigureElasticSearchRequest)
'request'=>array(),
),
);
`
如何保存记录
这是自动的,每次保存后,该行为都会将该记录发布到 ElasticSearch 索引中。
如果您想手动索引任何模型` $data` 数组(使用来自此模型的字段),您可以在您的` Model` 中执行以下操作
`
$data=$this->read(null,'1234');
$id=$data[$this->alias][$this->primaryKey];
$success=$this->saveToIndex($id,$data);
`
如果您有一个简单的字符串,您想在` Model` 上的记录中进行索引,那么您可以使用
`
$id='1234';
$success=$this->saveIndexDataToIndex($id,'Thisisacustomstring,thiswillbeindexed');
`
自定义要保存到索引中的数据
您可以在您的模型中指定一些方法,这些方法会覆盖基本功能。
在您的模型中创建此方法,以获取用于索引的自定义数据。它应该返回单个记录的数据数组,类似于` find(‘first’)`
`
$findFirstData=$this->getDataForIndex($id)
`
在您的模型中创建此方法,以将数据数组处理成用于索引的字符串。
它期望从` $this->data` 中获取其数据数组,而不是从传入的参数中获取
它应该返回一个字符串(将存储在索引中的文本)
`
$indexText=$this->indexData()
`
在您的模型中创建此方法,以清理或后处理索引文本。您可以替换术语、字符或您喜欢的任何内容。
`
$indexText=$this->cleanForIndex($indexText)
`
如何重新索引所有记录
在任何模型中,您可以运行` reIndexAll($conditions)`,它会遍历您的数据并重新索引所有数据... 这可能非常慢...
`
//thisisreallyslow,butitwillre-indexeverything(create/updateindexes)
$statusString=$this->reIndexAll();
//oryoucanpassinanyconditionsyouliketolimitthescopeofthereIndex
$statusString=$this->reIndexAll(array(
'modified>'=>date('Y-m-d00:00:00',strtotime('-2months')),
));
`
如何搜索
此行为的核心搜索方法是` searchAndReturnAssociationKeys`,它只返回` Model` 的` id`。
`
$primaryKeys=$this->searchAndReturnAssociationKeys($term);
`
以及` $optionsForElasticSearchRequest`(` limit`、` page`)。
`
$primaryKeys=$this->searchAndReturnAssociationKeys($term,$optionsForElasticSearchRequest);
`
这是一个非常有用的方法,它可以轻松地添加到任何` conditions` 数组中。
`
$conditions=array(
"{$this->alias}.{$this->primaryKey}"=>$this->searchAndReturnAssociationKeys('SearchTerm'),
);
`
如果您使用的是 CakeDC/search 插件,您可以使用它来创建子查询或查询过滤器...(这很棒!)
如何按最佳匹配结果进行搜索
搜索结果通常按与搜索词的最佳匹配排序。
`
$sortedIds=$this->searchAndReturnAssociationKeys('SearchTerm');
$results=$this->find('all',array(
'conditions'=>array(
"{$this->alias}.{$this->primaryKey}"=>$sortedIds
)
));
$results=$this->searchResultsResort($results,$sortedIds);
`
便捷搜索、排序和返回数据
如果您只想获取搜索结果,而没有其他条件,那么操作非常简单
`
$findAllResults=$this->search($term)
`
以下是所有可能的参数...
`
$findAllResults=$this->search($term,$optionsForFindAll,$optionsForElasticSearchRequest);
`
背景
此项目在很大程度上基于`Searchable/SearchIndex`_ 插件/行为,以及我之前的分叉版本。原始版本将所有索引数据存储到一个带有全文索引的 MySQL 表中。它运行得很好,但它只适用于 MyISAM 表引擎,而且不提供所有方便的搜索语法/功能。
最初,这是使用`Elasitc`_ 插件/数据源,它运行良好... 但是由于数据存储模式(作为 CakePHP 嵌套模型)以及所有模型的所有数据都存储在 ElasticSearch 上的同一“表”中,因此存在不必要的复杂性。此外,Elastic 模型需要 curl,这还不错,但并不需要。
现在,ElasticSearchIndex 使用`Icing.Lib/ElasticSearch`_ 与 ElasticSearch 进行交互。
通过“数据源”而不是通过“数据库”进行交互有点奇怪,但是 Lib 实际上是 HttpSocket 实用程序的扩展,它旨在促进原始交互(您手动创建要发送的任何数据)以及它具有的工具,可以帮助自动执行简单的数据传递。
归属
此项目是 Searchable/SearchIndex 的扩展,并参考了 Elastic 数据源... 基础工作是他们完成的。非常感谢!
- https://github.com/dkullmann/CakePHP-Elastic-Search-DataSource
- https://github.com/connrs/Searchable-Behaviour-for-CakePHP 我的分叉版本
- https://github.com/AudiologyHoldings/Icing
当然还有您... 欢迎拉取请求!
许可证
此代码根据 MIT 许可证发布
版权所有 (C) 2013–2014 Alan Blount alan@zeroasterisk.com https://github.com/zeroasterisk/
特此授予任何人免费获得本软件副本和相关文档文件(“软件”)的副本,不受限制地处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件的权利,以及允许接收软件的人员这样做,但须遵守以下条件:
上述版权声明和本许可声明应包含在软件的所有副本或重要部分中。
软件按“现状”提供,不提供任何形式的明示或暗示保证,包括但不限于适销性、特定目的的适用性和非侵权的保证。在任何情况下,作者或版权持有人均不对因软件或使用或其他处理软件而引起的任何索赔、损害或其他责任负责,无论是在合同、侵权行为或其他方面,以及由此产生的或与之相关的任何索赔、损害或其他责任。