自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Elasticsearch實戰(zhàn)指南:讓你的業(yè)務(wù)搜索飛起來

數(shù)據(jù)庫 其他數(shù)據(jù)庫
當(dāng)你的MySQL數(shù)據(jù)庫查詢突然從0.5秒飆升到15秒,當(dāng)你的產(chǎn)品經(jīng)理第20次提出"模糊搜索要支持同義詞聯(lián)想"時——是時候重新認(rèn)識這個改變搜索游戲規(guī)則的分布式搜索引擎了。

當(dāng)你的MySQL數(shù)據(jù)庫查詢突然從0.5秒飆升到15秒,當(dāng)你的產(chǎn)品經(jīng)理第20次提出"模糊搜索要支持同義詞聯(lián)想"時——是時候重新認(rèn)識這個改變搜索游戲規(guī)則的分布式搜索引擎了。

1.為什么Elasticsearch是新時代的“數(shù)據(jù)引擎”?

傳統(tǒng)數(shù)據(jù)庫的三大死穴

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

ES的破局武器

  • 分布式架構(gòu):線性擴(kuò)展支撐 PB 級數(shù)據(jù)
  • 倒排索引:毫秒級響應(yīng)關(guān)鍵詞搜索
  • 分詞引擎:中文/拼音/同義詞精準(zhǔn)匹配

2.五大場景+完整代碼:從入門到實戰(zhàn)

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

痛點

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

代碼實現(xiàn)

// 商品實體類
@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
}
// 搜索服務(wù)
@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());
    }
}

推薦系統(tǒng)——讓用戶“欲罷不能”

痛點

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

代碼實現(xiàn)

// 用戶畫像實體
@Document(indexName = "user_profiles")
public class UserProfile {
    @Field(type = FieldType.Keyword)
    private String userId;
    
    // 用戶興趣標(biāo)簽(可動態(tài)更新)
    @Field(type = FieldType.Keyword)
    private List<String> tags;
    
    @GeoPointField
    private GeoPoint lastLocation;
}
// 附近相似用戶推薦
public List<UserProfile> recommendUsers(String userId, int radiusKm) {
    UserProfile current = getUserById(userId); // 獲取當(dāng)前用戶
    
    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 // 標(biāo)簽匹配
                    .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函數(shù)消耗大)
  • 無法支持復(fù)雜地理圍欄

完整實現(xiàn)

// 商家實體(含地理位置)
@Document(indexName = "shops")
public class Shop {
    @Id
    private String id;
    
    @GeoPointField // 關(guān)鍵注解!
    private GeoPoint location;
    
    @Field(type = FieldType.Text)
    private String name;
}
// 附近商家服務(wù)
@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());
    }
}
// 接口調(diào)用示例
@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如何碾壓傳統(tǒng)方案

場景

數(shù)據(jù)量

MySQL耗時

ES耗時

優(yōu)勢倍數(shù)

商品搜索

1000萬

4.2s

28ms

150x

附近商家查詢

50萬

920ms

15ms

61x

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

事務(wù)場景:訂單支付等需強(qiáng)一致性時,仍需結(jié)合MySQL

冷數(shù)據(jù)存儲:歷史歸檔數(shù)據(jù)建議轉(zhuǎn)存至OSS

精確統(tǒng)計:UV去重請用HyperLogLog

5.小結(jié)

從電商搜索到地理圍欄,Elasticsearch 正在重新定義數(shù)據(jù)處理的邊界。當(dāng)你的業(yè)務(wù)面臨以下挑戰(zhàn)時,就是時候考慮 ES 了

  • 數(shù)據(jù)量超過千萬級
  • 需要復(fù)雜搜索/聚合
  • 對實時性要求高
責(zé)任編輯:武曉燕 來源: JAVA充電
相關(guān)推薦

2019-03-25 08:05:35

Elasticsear優(yōu)化集群

2011-04-13 10:51:58

MATLAB

2020-09-29 07:54:05

Express 飛起

2024-06-12 12:28:23

2025-04-15 00:00:00

2019-11-05 10:35:57

SpringBoot調(diào)優(yōu)Java

2023-03-01 23:59:23

Java開發(fā)

2021-07-13 07:52:03

SQL面試COUNT(*)

2024-11-25 18:00:00

C#代碼編程

2022-10-09 18:14:31

訂單系統(tǒng)分庫分表

2021-01-04 15:11:57

開發(fā) IDEA代碼

2024-11-27 09:46:34

2011-02-25 08:39:11

QFabric數(shù)據(jù)中心Juniper

2013-01-07 09:34:43

CodeLoveBAT

2025-01-17 09:23:31

2016-01-19 17:03:59

數(shù)據(jù)中心網(wǎng)絡(luò)華為

2011-09-27 13:25:05

Web

2022-09-02 08:21:24

idea插件

2016-05-11 09:18:21

AWS云數(shù)據(jù)倉庫Redshift

2023-11-10 18:03:04

業(yè)務(wù)場景SQL
點贊
收藏

51CTO技術(shù)棧公眾號