TP5.0如何实现一个完整的网站使用ES实现的文章搜索功能?使用场景是什么?底层原理是什么?
使用ThinkPHP (TP) 5.0 和 Elasticsearch (ES) 实现文章搜索功能是一种常见的需求,尤其是在需要高效全文搜索的场景下。
·
使用ThinkPHP (TP) 5.0 和 Elasticsearch (ES) 实现文章搜索功能是一种常见的需求,尤其是在需要高效全文搜索的场景下。
使用场景
- 全文搜索:用户可以通过关键词搜索到包含这些关键词的文章。
- 智能排序:根据相关性、发布时间等因素对搜索结果进行排序。
- 高级过滤:支持按照类别、作者等条件进行过滤搜索。
底层原理
Elasticsearch 是一个分布式的搜索和分析引擎,它使用倒排索引技术来快速检索文档。当文档被索引时,ES 会将文档中的每一个词作为键,文档ID作为值存入索引中。这样,当你查询某个词时,ES 可以迅速找到包含这个词的所有文档。
实现步骤
1. 准备环境
确保你的开发环境中已经安装了 PHP、Composer、MySQL 数据库以及 Elasticsearch。
2. 创建 TP5.0 项目
通过 Composer 创建一个新的 TP5.0 项目。
composer create-project topthink/think tp5.0
cd tp5.0
3. 安装 Elasticsearch 客户端
安装官方提供的 PHP 客户端来与 ES 交互。
composer require elasticsearch/elasticsearch
4. 创建文章模型和控制器
创建一个用于存储文章信息的数据模型,并设置对应的控制器来处理文章的 CRUD 操作。
5. 文章索引化
每次新增或修改文章时,都需要更新 ES 中的文章索引。
// 假设这是你的模型类中的方法
public function indexDocument($article)
{
$client = \Elasticsearch\ClientBuilder::create()->build();
$params = [
'index' => 'articles',
'type' => '_doc',
'id' => $article['id'],
'body' => $article
];
$client->index($params);
}
// 在保存文章时调用此方法
public function saveArticle($articleData)
{
$article = new ArticleModel();
$article->save($articleData);
$this->indexDocument($articleData);
}
6. 实现搜索功能
创建一个用于搜索文章的方法,该方法会从 ES 中查询数据,并返回给前端。
public function searchArticles($query)
{
$client = \Elasticsearch\ClientBuilder::create()->build();
$params = [
'index' => 'articles',
'body' => [
'query' => [
'match' => [
'content' => $query
]
]
]
];
$results = $client->search($params);
return $results['hits']['hits'];
}
7. 前端展示
在前端页面中添加搜索框,并使用 AJAX 技术来异步请求搜索结果,然后在页面上显示出来。
<form id="search-form">
<input type="text" name="query" placeholder="Search articles...">
<button type="submit">Search</button>
</form>
<div id="search-results"></div>
<script>
document.getElementById('search-form').addEventListener('submit', function(event) {
event.preventDefault();
const query = this.querySelector('input[name=query]').value;
fetch('/api/search?q=' + encodeURIComponent(query))
.then(response => response.json())
.then(data => {
const resultsDiv = document.getElementById('search-results');
resultsDiv.innerHTML = ''; // 清空结果
data.forEach(article => {
const div = document.createElement('div');
div.innerHTML = `<h2>${article._source.title}</h2><p>${article._source.content}</p>`;
resultsDiv.appendChild(div);
});
});
});
</script>
以上步骤给出了一个基本的实现框架,具体细节如错误处理、分页、安全验证等可能需要进一步完善。
更多推荐
所有评论(0)