elasticsearch - 如何在弹性搜索中存储房地产数据?
问题描述
我有房地产数据。我正在考虑将其存储到弹性搜索中,以允许用户实时搜索数据库。
我希望能够让我的用户按价格、地块大小、建造年份、总卧室等关键字段进行搜索。但是,我还希望能够让用户按关键字或“有游泳池”等便利设施进行过滤, “有水疗中心”, “停车位”, “社区”..
此外,我需要保留一个不同的属性类型、属性状态、学校、社区等列表,以便我可以创建下拉菜单供我的用户选择。
存储的数据结构应该是什么样的?如何维护不同学校、社区、类型的列表以使用它来创建下拉菜单供用户选择?
我拥有的当前数据基本上是一个键/值对。我可以在将其存储到 Elastic Search 之前对其进行清理和标准化,但对什么被认为是存储这些数据的好方法感到困惑?
解决方案
根据您的问题,我将提供基线映射和带有构面/过滤器的基本查询供您开始使用。
映射
PUT test_jay
{
"mappings": {
"properties": {
"amenities": {
"type": "keyword"
},
"description": {
"type": "text"
},
"location": {
"type": "geo_point"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"status": {
"type": "keyword"
},
"type": {
"type": "keyword"
}
}
}
}
我们将使用“关键字”字段类型,您将始终像下拉列表一样进行精确匹配。
对于我们只想进行全文搜索的字段,如描述,我们使用“文本”类型。在某些情况下,例如标题,我希望同时拥有两种字段类型。
我创建了一个 location geo_type 字段,以防您想将您的属性放在地图中或进行基于距离的搜索,例如附近的房屋。
对于便利设施,关键字字段类型足以存储一系列便利设施。
提取文档
POST test_jay/_doc
{
"name": "Nice property",
"description": "nice located fancy property",
"location": {
"lat": 37.371623,
"lon": -122.003338
},
"amenities": [
"Pool",
"Parking",
"Community"
],
"type": "House",
"status": "On sale"
}
请记住关键字字段区分大小写!
搜索查询
POST test_jay/_search
{
"query": {
"bool": {
"must": {
"multi_match": {
"query": "nice",
"fields": [
"name",
"description"
]
}
},
"filter": [
{
"term": {
"status": "On sale"
}
},
{
"term": {
"amenities":"Pool"
}
},
{
"term": {
"type": "House"
}
}
]
}
},
"aggs": {
"amenities": {
"terms": {
"field": "amenities",
"size": 10
}
},
"status": {
"terms": {
"field": "status",
"size": 10
}
},
"type": {
"terms": {
"field": "type",
"size": 10
}
}
}
}
多重匹配部分将在标题和描述字段中进行全文搜索。您正在使用常规搜索框填写此内容。
然后过滤器部分由下拉列表填充。
查询响应
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "test_jay",
"_type" : "_doc",
"_id" : "zWysGHgBLiMtJ3pUuvZH",
"_score" : 0.2876821,
"_source" : {
"name" : "Nice property",
"description" : "nice located fancy property",
"location" : {
"lat" : 37.371623,
"lon" : -122.003338
},
"amenities" : [
"Pool",
"Parking",
"Community"
],
"type" : "House",
"status" : "On sale"
}
}
]
},
"aggregations" : {
"amenities" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "Community",
"doc_count" : 1
},
{
"key" : "Parking",
"doc_count" : 1
},
{
"key" : "Pool",
"doc_count" : 1
}
]
},
"type" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "House",
"doc_count" : 1
}
]
},
"status" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "On sale",
"doc_count" : 1
}
]
}
}
}
使用查询响应,您可以为将来的过滤器填充构面。
我建议您尝试一下,然后再提出更具体的问题。
推荐阅读
- javascript - 如何按“键”与适当标题下方列出的关联数据进行分组
- php - 如何允许用户添加脚本,如 fb 像素代码、分析跟踪代码、自定义脚本……并保护平台免受攻击
- javascript - 将包含多个数组的 JSON 字符串转换为 C# 数组的问题
- ios - iOS iCloud 钥匙串 2 警报
- apex - Apex DateTime 到 String 然后传递参数
- r - 对满足两个条件的变量使用 mutate_at dplyr R
- javascript - 发生onblur时如何获取textarea的当前编辑值?
- python - 如何为小部件创建不同的字体大小但允许它们在 PySide2 中使用字体对话框进行缩放?
- python - Visual Studio Code - 缺少图标“在终端中运行 Pyrhon 文件”
- asp.net - 发布 Devexpress dll