《基于 SpringBoot + MySQL + Elasticsearch 的房产租赁信息搜索平台》

✅ 全文检索

✅ 中文分词

✅ 高亮 / 分页 / 筛选

✅ 数据同步

✅ 技术深度足够,答辩老师基本不会为难你


一、项目背景(论文 / 实战通用)

随着房产租赁市场的发展,用户对房源搜索的体验要求越来越高:

  • 传统 SQL LIKE查询性能差、匹配不智能

  • 无法支持模糊、同义词、纠错

  • 筛选条件多,组合复杂

  • 数据量大时响应慢

本系统基于 SpringBoot + MySQL + Elasticsearch,实现:

✅ 房源信息全文检索

✅ 中文分词 & 高亮显示

✅ 多条件组合筛选

✅ MySQL ↔ ES 数据同步

✅ 近实时搜索


二、技术架构

前端(Vue / Thymeleaf)
↓
SpringBoot
├── 搜索接口(ES)
├── 房源管理(MySQL)
├── 数据同步模块
↓
MySQL(源数据)
Elasticsearch(全文索引)

技术

作用

SpringBoot

快速开发

MyBatis

ORM

MySQL

持久化存储

Elasticsearch 7.x

全文检索

IK 分词器

中文分词

RestHighLevelClient

ES Java 客户端


三、系统功能模块

房产租赁搜索平台
├── 房源管理模块
│   ├── 发布房源
│   └── 编辑 / 下架
├── 全文检索模块(⭐核心)
│   ├── 关键词搜索
│   ├── 高亮显示
│   └── 分页排序
├── 组合筛选模块
│   ├── 价格区间
│   ├── 区域 / 户型
│   └── 标签筛选
├── 数据同步模块
│   └── MySQL → ES
└── 用户模块

四、数据库设计(MySQL)

1️⃣ 房源表 house

CREATE TABLE house (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  title VARCHAR(100),
  description TEXT,
  price DECIMAL(10,2),
  area DECIMAL(8,2),
  room_count INT,
  hall_count INT,
  floor INT,
  total_floor INT,
  direction VARCHAR(20),
  district VARCHAR(50),
  address VARCHAR(200),
  tags VARCHAR(200),   -- 近地铁,精装修
  status INT DEFAULT 1,
  create_time DATETIME,
  update_time DATETIME
);

五、ES 索引设计(⭐核心)

1️⃣ 创建索引 + IK 分词

PUT /house_index
{
  "settings": {
    "number_of_shards": 1,
    "analysis": {
      "analyzer": {
        "ik_max_word": {
          "type": "ik_max_word"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "id":         { "type": "long" },
      "title":      { "type": "text", "analyzer": "ik_max_word" },
      "description":{ "type": "text", "analyzer": "ik_max_word" },
      "price":      { "type": "double" },
      "area":       { "type": "double" },
      "roomCount":  { "type": "integer" },
      "district":   { "type": "keyword" },
      "tags":       { "type": "keyword" },
      "createTime": { "type": "date" }
    }
  }
}

2️⃣ 实体类 HouseES

@Data
@Document(indexName = "house_index")
public class HouseES {

    private Long id;
    private String title;
    private String description;
    private Double price;
    private Double area;
    private Integer roomCount;
    private String district;
    private List<String> tags;
    private Date createTime;
}

六、数据同步(MySQL → ES)

方式一:同步写入(简单)

@Transactional
public void save(House house) {
    // 1. 写 MySQL
    houseMapper.insert(house);

    // 2. 写 ES
    HouseES es = convert(house);
    restHighLevelClient.index(
        new IndexRequest("house_index")
            .id(house.getId().toString())
            .source(JSON.toJSONString(es), XContentType.JSON)
    );
}

方式二:定时同步(推荐)

@Scheduled(cron = "0 */5 * * * ?")
public void sync() {
    List<House> list = houseMapper.selectUpdatedAfter(lastSyncTime);
    for (House h : list) {
        updateES(h);
    }
}

七、全文检索核心实现(⭐重点)

1️⃣ 构建搜索条件

SearchRequest request = new SearchRequest("house_index");
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

// 1. 全文检索
if (StringUtils.isNotBlank(keyword)) {
    boolQuery.must(QueryBuilders.multiMatchQuery(keyword, "title", "description"));
}

// 2. 价格区间
if (minPrice != null) {
    boolQuery.filter(QueryBuilders.rangeQuery("price").gte(minPrice));
}
if (maxPrice != null) {
    boolQuery.filter(QueryBuilders.rangeQuery("price").lte(maxPrice));
}

// 3. 区域
if (StringUtils.isNotBlank(district)) {
    boolQuery.filter(QueryBuilders.termQuery("district", district));
}

// 4. 户型
if (roomCount != null) {
    boolQuery.filter(QueryBuilders.termQuery("roomCount", roomCount));
}

2️⃣ 高亮 + 分页

// 高亮
HighlightBuilder highlight = new HighlightBuilder()
        .field("title")
        .preTags("<em>")
        .postTags("</em>");

// 分页
SearchSourceBuilder source = new SearchSourceBuilder()
        .query(boolQuery)
        .highlighter(highlight)
        .from((pageNum - 1) * pageSize)
        .size(pageSize)
        .sort("createTime", SortOrder.DESC);

request.source(source);

3️⃣ 解析结果

SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

for (SearchHit hit : response.getHits()) {
    HouseES house = JSON.parseObject(hit.getSourceAsString(), HouseES.class);

    // 取高亮
    Map<String, HighlightField> hl = hit.getHighlightFields();
    if (hl.containsKey("title")) {
        house.setTitle(hl.get("title").fragments()[0].string());
    }
}

八、搜索接口(Controller)

@GetMapping("/search")
public R<PageResult<HouseES>> search(
        @RequestParam(required = false) String keyword,
        @RequestParam(required = false) Double minPrice,
        @RequestParam(required = false) Double maxPrice,
        @RequestParam(defaultValue = "1") Integer pageNum
) {
    return R.ok(searchService.search(keyword, minPrice, maxPrice, pageNum));
}

九、搜索页面(前端示例)

<form action="/search">
  <input type="text" name="keyword" placeholder="搜索小区/商圈/地铁">
  价格:
  <input name="minPrice" placeholder="最低价">
  ~
  <input name="maxPrice" placeholder="最高价">
  <button>搜索</button>
</form>

<div th:each="h : ${list}">
  <h3 th:utext="${h.title}"></h3>
  <p th:text="${h.description}"></p>
  <span th:text="${h.price} + '元/月'"></span>
</div>

十、系统特色(⭐答辩亮点)

✅ Elasticsearch 全文检索

✅ IK 中文分词 + 高亮

✅ 多条件组合筛选

✅ MySQL ↔ ES 数据同步

✅ 近实时搜索

✅ 可扩展为租房平台核心搜索


十一、可扩展方向(工作量拉满)

✅ 地理位置搜索(geo_point)

✅ 自动补全 / 搜索建议(suggest)

✅ 竞价排名 / 房源置顶

✅ 搜索热词统计

✅ 分布式 ES 集群

✅ 接入大模型做智能问答


十二、毕设论文结构建议

章节

内容

第1章

绪论

第2章

相关技术

第3章

需求分析

第4章

系统设计(ES 索引设计)

第5章

系统实现(全文检索核心)

第6章

系统测试

第7章

总结与展望

更多推荐