
本文共 3944 字,大约阅读时间需要 13 分钟。
深入搜索
在开始使用 Elasticsearch之前,我们需要涵盖基本工具并对它们进行详细描述。这将允许我们逐步利用 Elasticsearch 搜索数据。然而,经过使用一段时间后,我们可能会发现一些不足:查询匹配不够灵活,结果排名不够精确,跨领域搜索也不够具体。
为了进一步提升,我们需要理解数据以及如何高效地搜索到它们。本章将介绍如何索引和查询数据,从而充分发挥词的相似度(word proximity)、部分匹配(partial matching)、模糊匹配(fuzzy matching)和语言感知(language awareness)的优势。
理解每个查询如何贡献相关度评分(_score》有助于调试我们的查询,确保我们认为的最佳匹配文档能出现在搜索结果榜首,同时减少无关的“长尾”(long tail)内容。搜索不仅仅是全文搜索,我们的大部分数据都是结构化的,如日期和数字。我们将从结构化搜索与全文搜索的结合方式开始,逐步深入了解如何高效地处理结构化数据。
探索你的数据
现在我们已经掌握了基本的搜索知识,接下来我们尝试一些更真实的数据集。我准备了一个关于客户银行账户信息的虚构JSON文档样本。每个文档都有以下模式:
{ "account_number": 0, "balance": 16623, "firstname": "Bradshaw", "lastname": "Mckenzie", "age": 29, "gender": "F", "address": "244 Columbus Place", "employer": "Euron", "email": "bradshawmckenzie@euron.com", "city": "Hobucken", "state": "CO"}
这个数据集是随机生成的,请忽略其实际意义。
加载示例数据集
你可以通过以下命令下载并索引示例数据集(accounts.json):
curl -H "Content-Type: application/json" -XPOST 'http://localhost:9200/bank/account/_bulk?pretty&refresh' --data-binary "@accounts.json"
运行完成后,你可以查询索引状态:
curl 'localhost:9200/_cat/indices?v'
这意味着我们成功将1000个文件索引到bank
索引(类型account
)中。
搜索API
现在让我们进行一些简单的搜索。Elasticsearch支持两种主要的搜索方式:一种是发送搜索参数作为请求体,另一种是通过URI参数。以下是返回银行索引中所有文档的示例查询:
GET /bank/_search?query=*&sort=account_number:asc&pretty
解析查询:
*
:匹配所有文档sort=account_number:asc
:按account_number
升序排序pretty
:美化输出格式
响应示例:
{ "took": 63, "timed_out": false, "shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1000, "max_score": null, "hits": [ { "_index": "bank", "_type": "account", "_id": "0", "sort": [0], "_score": null, "_source": { "account_number": 0, "balance": 16623, "firstname": "Bradshaw", "lastname": "Mckenzie", "age": 29, "gender": "F", "address": "244 Columbus Place", "employer": "Euron", "email": "bradshawmckenzie@euron.com", "city": "Hobucken", "state": "CO" } }, # 其他文档... ] }}
查询语言介绍
Elasticsearch提供了一种强大的JSON式查询语言,称为Query DSL。我们从基本查询开始。
以下是返回account_number
为20的示例:
GET /bank/_search{"query":{"match":{"account_number":20}}
以下是返回地址中包含“mill”的示例:
GET /bank/_search{"query":{"match":{"address":"mill"}}
以下是返回地址中包含“mill lane”的示例:
GET /bank/_search{"query":{"match_phrase":{"address":"mill lane"}}
布尔查询
Bool查询允许我们使用布尔逻辑组合多个查询条件。以下是两个字段都包含“mill”的示例:
GET /bank/_search{"query":{"bool":{"must":[{"match":{"address":"mill"}},{"match":{"address":"lane"}}]}}
以下是地址中包含“mill”或“lane”的示例:
GET /bank/_search{"query":{"bool":{"should":[{"match":{"address":"mill"}},{"match":{"address":"lane"}}]}}
以下是地址既不包含“mill”也不包含“lane”的示例:
GET /bank/_search{"query":{"bool":{"must_not":[{"match":{"address":"mill"}},{"match":{"address":"lane"}}]}}
以下是40岁但不是ID州的人的示例:
GET /bank/_search{"query":{"bool":{"must":[{"match":{"age":"40"}}],"must_not":[{"match":{"state":"ID"}}]}}
过滤器
除了match
查询,Elaticsearch还提供了filter
条款,用于仅进行过滤,而不影响分数计算。以下是返回余额在20000到30000之间的示例:
GET /bank/_search{"query":{"bool":{"must":{"match_all":{}},{"filter":{"range":{"balance":{"gte":20000,"lte":30000}}}}}
聚合
聚合功能允许我们从数据中提取统计信息。以下是按状态分组并计算每个状态的文档数量:
GET /bank/_search{"size":0,"aggs":{"group_by_state":{"terms":{"field":"state.keyword"}}}}
以下是按状态并按平均余额排序的示例:
GET /bank/_search{"size":0,"aggs":{"group_by_state":{"terms":{"field":"state.keyword","order":{"average_balance":"desc"}},"aggs":{"average_balance":{"avg":{"field":"balance"}}}}}
以下是按年龄段和性别分组并计算平均余额的示例:
GET /bank/_search{"size":0,"aggs":{"group_by_age":{"range":{"field":"age","ranges":[{"from":20,"to":30},{"from":30,"to":40},{"from":40,"to":50}]),"aggs":{"group_by_gender":{"terms":{"field":"gender.keyword"},"aggs":{"average_balance":{"avg":{"field":"balance"}}}}}}"}
发表评论
最新留言
关于作者
