成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Elasticsearch實戰指南:讓你的業務搜索飛起來

數據庫 其他數據庫
當你的MySQL數據庫查詢突然從0.5秒飆升到15秒,當你的產品經理第20次提出"模糊搜索要支持同義詞聯想"時——是時候重新認識這個改變搜索游戲規則的分布式搜索引擎了。

當你的MySQL數據庫查詢突然從0.5秒飆升到15秒,當你的產品經理第20次提出"模糊搜索要支持同義詞聯想"時——是時候重新認識這個改變搜索游戲規則的分布式搜索引擎了。

1.為什么Elasticsearch是新時代的“數據引擎”?

傳統數據庫的三大死穴

  • 模糊查詢性能差(LIKE耗時隨數據量指數級上升)
  • 缺乏智能排序(無法根據用戶行為動態加權)
  • 擴展性弱(分庫分表成本高)

ES的破局武器

  • 分布式架構:線性擴展支撐 PB 級數據
  • 倒排索引:毫秒級響應關鍵詞搜索
  • 分詞引擎:中文/拼音/同義詞精準匹配

2.五大場景+完整代碼:從入門到實戰

電商搜索——讓用戶“一搜即中”

痛點

  • 用戶搜索“蘋果手機”時,無法智能匹配“iPhone”
  • 搜索結果排序僵化(無法綜合銷量/評分/價格動態排序)

代碼實現

// 商品實體類
@Document(indexName = "products")
public class Product {
    @Id
    private String id;
    
    // 使用ik_max_word分詞器
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String title; 
    
    private Double price;
    private Long sales;
    // getters/setters
}
// 搜索服務
@Service 
public class ProductService {
    @Autowired
    private ElasticsearchOperations esOperations;
    public List<Product> search(String keyword) {
        Query query = NativeQuery.builder()
            .withQuery(q -> q
                .match(m -> m      // 多字段匹配
                    .field("title")
                    .field("description")
                    .query(keyword)
                )
            )
            .withSort(s -> s     // 綜合排序:銷量倒序 > 價格升序
                .field(f -> f.field("sales").order(SortOrder.Desc))
                .field(f -> f.field("price").order(SortOrder.Asc))
            )
            .build();
        return esOperations.search(query, Product.class)
            .stream().map(SearchHit::getContent).collect(Collectors.toList());
    }
}

推薦系統——讓用戶“欲罷不能”

痛點

  • 用戶興趣變化快,推薦結果更新延遲高
  • 無法實時結合用戶位置/行為調整策略

代碼實現

// 用戶畫像實體
@Document(indexName = "user_profiles")
public class UserProfile {
    @Field(type = FieldType.Keyword)
    private String userId;
    
    // 用戶興趣標簽(可動態更新)
    @Field(type = FieldType.Keyword)
    private List<String> tags;
    
    @GeoPointField
    private GeoPoint lastLocation;
}
// 附近相似用戶推薦
public List<UserProfile> recommendUsers(String userId, int radiusKm) {
    UserProfile current = getUserById(userId); // 獲取當前用戶
    
    Query query = NativeQuery.builder()
        .withQuery(q -> q
            .bool(b -> b
                .must(m -> m.geoDistance(g -> g // 地理過濾
                    .field("lastLocation")
                    .distance(radiusKm + "km")
                    .location(l -> l.latlon(ll -> 
                        ll.lat(current.getLastLocation().lat())
                          .lon(current.getLastLocation().lon())
                    ))
                ))
                .must(m -> m.terms(t -> t // 標簽匹配
                    .field("tags")
                    .terms(t2 -> t2.value(current.getTags()))
                )
            )
        )
        .build();
    return esOperations.search(query, UserProfile.class)
        .stream().map(SearchHit::getContent)
        .collect(Collectors.toList());
}

地理搜索——讓“附近的人”觸手可及

痛點

  • MySQL地理計算性能差(ST_Distance函數消耗大)
  • 無法支持復雜地理圍欄

完整實現

// 商家實體(含地理位置)
@Document(indexName = "shops")
public class Shop {
    @Id
    private String id;
    
    @GeoPointField // 關鍵注解!
    private GeoPoint location;
    
    @Field(type = FieldType.Text)
    private String name;
}
// 附近商家服務
@Service
public class ShopService {
    public List<Shop> findNearby(double lat, double lon, double radiusKm) {
        Query query = NativeQuery.builder()
            .withQuery(q -> q
                .geoDistance(g -> g
                    .field("location")
                    .distance(radiusKm + "km")
                    .location(gl -> gl.latlon(l -> l.lat(lat).lon(lon)))
            )
            .withSort(s -> s // 按距離排序
                .geoDistance(g -> g
                    .field("location")
                    .location(l -> l.latlon(ll -> ll.lat(lat).lon(lon))
                    .order(SortOrder.Asc))
            )
            .build();
        return esOperations.search(query, Shop.class)
            .stream().map(SearchHit::getContent)
            .collect(Collectors.toList());
    }
}
// 接口調用示例
@RestController
@RequestMapping("/shops")
public class ShopController {
    @GetMapping("/nearby")
    public List<Shop> getNearby(
        @RequestParam double lat, 
        @RequestParam double lon,
        @RequestParam(defaultValue = "3") double radius) {
        return shopService.findNearby(lat, lon, radius);
    }
}

3.性能對比:ES如何碾壓傳統方案

場景

數據量

MySQL耗時

ES耗時

優勢倍數

商品搜索

1000萬

4.2s

28ms

150x

附近商家查詢

50萬

920ms

15ms

61x

4.避坑指南:ES不是銀彈

事務場景:訂單支付等需強一致性時,仍需結合MySQL

冷數據存儲:歷史歸檔數據建議轉存至OSS

精確統計:UV去重請用HyperLogLog

5.小結

從電商搜索到地理圍欄,Elasticsearch 正在重新定義數據處理的邊界。當你的業務面臨以下挑戰時,就是時候考慮 ES 了

  • 數據量超過千萬級
  • 需要復雜搜索/聚合
  • 對實時性要求高
責任編輯:武曉燕 來源: JAVA充電
相關推薦

2019-03-25 08:05:35

Elasticsear優化集群

2020-09-29 07:54:05

Express 飛起

2011-04-13 10:51:58

MATLAB

2024-06-12 12:28:23

2025-04-15 00:00:00

2019-11-05 10:35:57

SpringBoot調優Java

2023-03-01 23:59:23

Java開發

2021-07-13 07:52:03

SQL面試COUNT(*)

2025-06-04 01:35:00

RocketMQ異步消息

2024-11-25 18:00:00

C#代碼編程

2025-06-26 02:15:00

2022-10-09 18:14:31

訂單系統分庫分表

2025-05-22 09:43:55

2021-01-04 15:11:57

開發 IDEA代碼

2024-11-27 09:46:34

2013-01-07 09:34:43

CodeLoveBAT

2011-02-25 08:39:11

QFabric數據中心Juniper

2025-01-17 09:23:31

2016-01-19 17:03:59

數據中心網絡華為

2025-05-22 08:04:43

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美v免费| 国产激情在线播放 | 一区二区三区国产精品 | 一级黄a视频 | 免费中文字幕 | 九九热这里 | 久久成人精品一区二区三区 | 国产一区二 | 欧美日韩高清免费 | 成人国产精品色哟哟 | 国产成人99久久亚洲综合精品 | 日韩视频一区二区三区 | 狠狠狠色丁香婷婷综合久久五月 | 蜜桃av一区二区三区 | 一区二区福利视频 | 亚洲一区二区在线视频 | 9久9久 | 国产日韩欧美一区 | 久久久久久久久久一区 | 操久久| 日韩毛片在线观看 | 中文字幕高清一区 | 久久久成人一区二区免费影院 | 国产高清一区二区三区 | 成人在线观看免费爱爱 | 欧美在线综合 | 国产中文字幕在线观看 | 国产精品区二区三区日本 | 欧美日韩精品免费 | 在线观看亚洲一区二区 | 日韩不卡一二区 | 香蕉久久久 | 久久久久久a | 一级大片 | 一级a性色生活片久久毛片 一级特黄a大片 | 国产黄色麻豆视频 | 你懂的国产 | 91免费看片| 国产剧情一区 | 少妇精品亚洲一区二区成人 | 久热国产精品视频 |