最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合MongoDB的完整操作指南

 更新時間:2026年02月10日 08:59:29   作者:J_liaty  
在實(shí)際項(xiàng)目開發(fā)中,合理封裝MongoDB的操作工具類,可以大幅提升代碼復(fù)用性和維護(hù)性,本文將帶你從零開始實(shí)現(xiàn)一個功能完善的MongoDB工具類,涵蓋基礎(chǔ)CRUD和高級查詢功能,需要的朋友可以參考下

依賴配置

pom.xml 中添加以下依賴:

<dependencies>
    <!-- SpringBoot Starter MongoDB -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    
    <!-- Lombok (可選,簡化實(shí)體類) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    
    <!-- Hutool工具包 (可選) -->
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.18</version>
    </dependency>
</dependencies>

配置文件

application.yml 中配置MongoDB連接信息:

基礎(chǔ)配置(使用URI方式)

spring:
  data:
    mongodb:
      # MongoDB連接URI
      # 格式:mongodb://[username:password@]host:port/database
      # 示例說明:
      # - mongodb://localhost:27017:本地MongoDB,默認(rèn)端口27017
      # - mongodb://admin:123456@localhost:27017:帶用戶名密碼的連接
      # - mongodb://host1:27017,host2:27017:連接副本集
      uri: mongodb://localhost:27017
      
      # 數(shù)據(jù)庫名稱
      # 說明:指定要使用的MongoDB數(shù)據(jù)庫
      # 注意:數(shù)據(jù)庫不存在時會自動創(chuàng)建
      database: my_database
      
      # 自動創(chuàng)建索引
      # 說明:啟動時自動為實(shí)體類上的@Indexed注解創(chuàng)建索引
      # 優(yōu)點(diǎn):開發(fā)環(huán)境方便,自動創(chuàng)建索引
      # 缺點(diǎn):生產(chǎn)環(huán)境可能影響啟動速度
      # 建議:生產(chǎn)環(huán)境設(shè)置為false,手動管理索引
      auto-index-creation: true

完整配置(詳細(xì)配置方式)

spring:
  data:
    mongodb:
      # ==================== 連接基礎(chǔ)配置 ====================
      
      # MongoDB服務(wù)器地址
      # 說明:可以是IP地址或域名
      # 示例:
      # - localhost:本地連接
      # - 192.168.1.100:指定IP地址
      # - mongodb.example.com:域名連接
      host: localhost
      
      # MongoDB服務(wù)器端口
      # 說明:MongoDB默認(rèn)端口為27017
      # 注意:確保端口沒有被防火墻阻止
      port: 27017
      
      # 數(shù)據(jù)庫名稱
      # 說明:指定要連接的數(shù)據(jù)庫名稱
      database: my_database
      
      # ==================== 認(rèn)證配置 ====================
      
      # 用戶名
      # 說明:如果MongoDB啟用了認(rèn)證,需要提供用戶名
      # 注意:用戶必須有對應(yīng)數(shù)據(jù)庫的訪問權(quán)限
      # 示例:admin用戶通常是管理員賬戶
      username: admin
      
      # 密碼
      # 說明:對應(yīng)用戶名的密碼
      # 安全建議:
      # - 生產(chǎn)環(huán)境不要明文存儲密碼
      # - 建議使用環(huán)境變量或加密配置
      # - 示例:${MONGODB_PASSWORD:admin123}
      password: admin123
      
      # 認(rèn)證數(shù)據(jù)庫
      # 說明:用戶認(rèn)證信息存儲的數(shù)據(jù)庫
      # 默認(rèn)值:admin
      # 注意:大多數(shù)用戶的認(rèn)證信息存儲在admin數(shù)據(jù)庫中
      authentication-database: admin
      
      # ==================== 索引配置 ====================
      
      # 自動創(chuàng)建索引
      # 說明:應(yīng)用啟動時自動創(chuàng)建索引
      # 開發(fā)環(huán)境:建議設(shè)置為true,方便開發(fā)
      # 生產(chǎn)環(huán)境:建議設(shè)置為false,手動管理索引更安全
      # 原因:
      # - 生產(chǎn)環(huán)境索引創(chuàng)建可能影響性能
      # - 可以提前規(guī)劃好索引,避免運(yùn)行時創(chuàng)建
      auto-index-creation: true
      
      # ==================== 連接池配置 ====================
      
      # 每個主機(jī)最小連接數(shù)
      # 說明:連接池中保持的最小連接數(shù)量
      # 作用:避免頻繁創(chuàng)建和銷毀連接的開銷
      # 建議:
      # - 低負(fù)載應(yīng)用:5-10
      # - 中等負(fù)載應(yīng)用:10-20
      # - 高負(fù)載應(yīng)用:20-50
      min-connections-per-host: 10
      
      # 每個主機(jī)最大連接數(shù)
      # 說明:連接池中允許的最大連接數(shù)量
      # 作用:限制并發(fā)連接數(shù),防止資源耗盡
      # 建議:
      # - 根據(jù)應(yīng)用并發(fā)量設(shè)置
      # - 一般設(shè)置為CPU核心數(shù)的2-4倍
      # - 例如:8核CPU可以設(shè)置為32-100
      max-connections-per-host: 100
      
      # 連接線程阻塞倍數(shù)
      # 說明:允許等待連接的最大線程數(shù)
      # 計(jì)算公式:max-connections-per-host × multiplier
      # 示例:100 × 5 = 500個線程可以等待連接
      # 作用:當(dāng)連接池耗盡時,允許一定數(shù)量的線程等待
      # 建議:一般設(shè)置為3-5倍
      threads-allowed-to-block-for-connection-multiplier: 5
      
      # 連接超時時間(毫秒)
      # 說明:獲取連接的最大等待時間
      # 默認(rèn)值:10000毫秒(10秒)
      # 作用:防止線程無限等待連接
      # 建議:
      # - 開發(fā)環(huán)境:5000-10000毫秒
      # - 生產(chǎn)環(huán)境:根據(jù)響應(yīng)時間要求調(diào)整
      # - 網(wǎng)絡(luò)不穩(wěn)定時可以適當(dāng)增加
      connection-timeout: 10000
      
      # Socket超時時間(毫秒)
      # 說明:Socket讀寫操作的超時時間
      # 默認(rèn)值:0(表示無超時,永久等待)
      # 作用:防止網(wǎng)絡(luò)故障導(dǎo)致請求掛起
      # 建議:
      # - 簡單查詢:30000-60000毫秒(30-60秒)
      # - 復(fù)雜查詢:120000毫秒(120秒)或更長
      # - 注意:超時時間要根據(jù)實(shí)際業(yè)務(wù)需求設(shè)置
      socket-timeout: 60000
      
      # ==================== 其他可選配置 ====================
      
      # 編解碼器(可選)
      # 說明:指定MongoDB驅(qū)動使用的編解碼器
      # 默認(rèn)值:org.bson.codecs.DocumentCodec
      # 用途:自定義文檔的編碼解碼邏輯
      # codec: com.example.mongodb.CustomCodec
      
      # UUID表示方式(可選)
      # 說明:UUID類型在MongoDB中的存儲格式
      # 可選值:
      # - JAVA_LEGACY:Java的傳統(tǒng)格式(3.0之前)
      # - STANDARD:標(biāo)準(zhǔn)格式(推薦)
      # - C_SHARP_LEGACY:C#的傳統(tǒng)格式
      # - PYTHON_LEGACY:Python的傳統(tǒng)格式
      # uuid-representation: STANDARD
      
      # 副本集名稱(可選)
      # 說明:連接副本集時指定的副本集名稱
      # 用途:連接副本集時必須指定
      # 示例:replica-set-name
      # replica-set-name: myReplicaSet
      
      # 讀取偏好(可選)
      # 說明:指定讀取數(shù)據(jù)的首選節(jié)點(diǎn)
      # 可選值:
      # - primary:只從主節(jié)點(diǎn)讀?。J(rèn))
      # - primaryPreferred:優(yōu)先從主節(jié)點(diǎn)讀取
      # - secondary:只從從節(jié)點(diǎn)讀取
      # - secondaryPreferred:優(yōu)先從從節(jié)點(diǎn)讀取
      # - nearest:從最近節(jié)點(diǎn)讀取
      # read-preference: secondaryPreferred
      
      # 寫關(guān)注級別(可選)
      # 說明:指定寫入操作的安全級別
      # 可選值:
      # - ACKNOWLEDGED:默認(rèn),確認(rèn)寫入主節(jié)點(diǎn)
      # - W1:確認(rèn)寫入主節(jié)點(diǎn)和一個從節(jié)點(diǎn)
      # - W2:確認(rèn)寫入主節(jié)點(diǎn)和兩個從節(jié)點(diǎn)
      # - MAJORITY:確認(rèn)寫入大多數(shù)節(jié)點(diǎn)
      # - UNACKNOWLEDGED:不等待確認(rèn),性能最好但不安全
      # write-concern: ACKNOWLEDGED

多環(huán)境配置示例

開發(fā)環(huán)境配置(application-dev.yml)

spring:
  data:
    mongodb:
      host: localhost
      port: 27017
      database: dev_database
      username: dev_user
      password: dev_password
      auto-index-creation: true
      # 開發(fā)環(huán)境連接池配置較小
      min-connections-per-host: 5
      max-connections-per-host: 20
      connection-timeout: 10000
      socket-timeout: 30000

測試環(huán)境配置(application-test.yml)

spring:
  data:
    mongodb:
      host: test-mongodb.example.com
      port: 27017
      database: test_database
      username: test_user
      password: ${MONGODB_TEST_PASSWORD}
      auto-index-creation: false
      # 測試環(huán)境連接池配置中等
      min-connections-per-host: 10
      max-connections-per-host: 50
      connection-timeout: 10000
      socket-timeout: 60000

生產(chǎn)環(huán)境配置(application-prod.yml)

spring:
  data:
    mongodb:
      # 生產(chǎn)環(huán)境使用URI方式連接副本集
      uri: mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@mongo1.example.com:27017,mongo2.example.com:27017,mongo3.example.com:27017/${MONGODB_DATABASE}?replicaSet=prodReplicaSet&connectTimeoutMS=10000&socketTimeoutMS=60000
      
      auto-index-creation: false
      
      # 生產(chǎn)環(huán)境連接池配置較大
      min-connections-per-host: 20
      max-connections-per-host: 100
      threads-allowed-to-block-for-connection-multiplier: 5
      connection-timeout: 10000
      socket-timeout: 60000
      
      # 生產(chǎn)環(huán)境使用副本集,配置讀取偏好和寫關(guān)注
      # read-preference: secondaryPreferred
      # write-concern: MAJORITY

配置參數(shù)詳解

連接池參數(shù)對比表

參數(shù)說明推薦值(小應(yīng)用)推薦值(大應(yīng)用)調(diào)優(yōu)建議
min-connections-per-host最小連接數(shù)5-1020-50根據(jù)平均并發(fā)量設(shè)置
max-connections-per-host最大連接數(shù)20-50100-200根據(jù)峰值并發(fā)量設(shè)置
threads-allowed-to-block-for-connection-multiplier阻塞倍數(shù)55一般不需要調(diào)整
connection-timeout連接超時(ms)1000010000網(wǎng)絡(luò)不穩(wěn)定時可增加
socket-timeoutSocket超時(ms)30000-6000060000-120000根據(jù)查詢復(fù)雜度調(diào)整

常見問題與解決方案

1. 連接超時問題

現(xiàn)象:應(yīng)用啟動或查詢時頻繁出現(xiàn)連接超時

解決方案

spring:
  data:
    mongodb:
      # 增加連接超時時間
      connection-timeout: 20000
      # 增加Socket超時時間
      socket-timeout: 120000
      # 增加連接池大小
      max-connections-per-host: 200

2. 副本集連接問題

現(xiàn)象:連接副本集時出現(xiàn)"not master and slaveOk=false"錯誤

解決方案

spring:
  data:
    mongodb:
      # 使用URI方式連接副本集
      uri: mongodb://user:pass@host1:27017,host2:27017,host3:27017/database?replicaSet=myReplicaSet&readPreference=secondaryPreferred

3. 認(rèn)證失敗問題

現(xiàn)象:認(rèn)證失敗,無法連接數(shù)據(jù)庫

解決方案

spring:
  data:
    mongodb:
      username: your_username
      password: your_password
      authentication-database: admin  # 確保指定正確的認(rèn)證數(shù)據(jù)庫

安全建議

密碼安全

  • 不要在配置文件中明文存儲密碼
  • 使用環(huán)境變量:${MONGODB_PASSWORD}
  • 使用加密配置中心

網(wǎng)絡(luò)安全

  • 生產(chǎn)環(huán)境不要使用localhost
  • 使用內(nèi)網(wǎng)IP或VPN
  • 配置MongoDB的防火墻規(guī)則

權(quán)限控制

  • 為不同環(huán)境創(chuàng)建不同的數(shù)據(jù)庫用戶
  • 遵循最小權(quán)限原則
  • 定期更換密碼

核心工具類實(shí)現(xiàn)

1. 響應(yīng)結(jié)果封裝類

package com.example.mongodb.common;

import lombok.Data;
import java.io.Serializable;

/**
 * 統(tǒng)一響應(yīng)結(jié)果封裝
 */
@Data
public class Result<T> implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    private Integer code;
    private String message;
    private T data;
    private Long total;
    
    public Result() {
    }
    
    public Result(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
    
    public static <T> Result<T> success(T data) {
        return new Result<>(200, "操作成功", data);
    }
    
    public static <T> Result<T> success(String message, T data) {
        return new Result<>(200, message, data);
    }
    
    public static <T> Result<T> error(String message) {
        return new Result<>(500, message, null);
    }
    
    public static <T> Result<T> error(Integer code, String message) {
        return new Result<>(code, message, null);
    }
    
    public Result<T> total(Long total) {
        this.total = total;
        return this;
    }
}

2. 分頁請求參數(shù)類

package com.example.mongodb.common;

import lombok.Data;

/**
 * 分頁請求參數(shù)
 */
@Data
public class PageRequest {
    
    /** 當(dāng)前頁碼 */
    private Integer pageNum = 1;
    
    /** 每頁條數(shù) */
    private Integer pageSize = 10;
    
    /** 排序字段 */
    private String sortField;
    
    /** 排序方式:asc/desc */
    private String sortOrder = "asc";
    
    public PageRequest() {
    }
    
    public PageRequest(Integer pageNum, Integer pageSize) {
        this.pageNum = pageNum;
        this.pageSize = pageSize;
    }
    
    public int getSkip() {
        return (pageNum - 1) * pageSize;
    }
}

3. 核心MongoDB工具類(詳細(xì)注釋版)

package com.example.mongodb.utils;

import com.example.mongodb.common.PageRequest;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.regex.Pattern;

/**
 * MongoDB工具類 - 提供完整的CRUD操作和高級查詢功能
 * 
 * ========================================
 * 使用說明:
 * ========================================
 * 1. 使用泛型<T>支持任意實(shí)體類型
 * 2. 基于MongoTemplate實(shí)現(xiàn),提供了豐富的封裝方法
 * 3. 支持事務(wù)、聚合、批量操作等高級特性
 * 4. 所有方法都有詳細(xì)注釋,方便理解和使用
 * 
 * @author 作者
 * @date 2026-02-09
 */
@Slf4j
@Component
public class MongoUtils<T> {
    
    // ==================== 核心依賴注入 ====================
    
    /**
     * MongoDB操作模板
     * 說明:Spring Data MongoDB的核心類,提供了對MongoDB數(shù)據(jù)庫的所有操作
     * 使用場景:執(zhí)行查詢、插入、更新、刪除等所有數(shù)據(jù)庫操作
     */
    @Autowired
    private MongoTemplate mongoTemplate;
    
    /**
     * 獲取集合名稱
     * 功能:根據(jù)實(shí)體類獲取對應(yīng)的MongoDB集合名稱(相當(dāng)于關(guān)系數(shù)據(jù)庫的表名)
     * 實(shí)現(xiàn)原理:通過@Document注解的collection屬性,或使用類名小寫形式
     * 
     * @param entityClass 實(shí)體類類型(帶@Document注解的類)
     * @return 集合名稱(MongoDB中的集合名,如"user"、"order"等)
     */
    private String getCollectionName(Class<?> entityClass) {
        return mongoTemplate.getCollectionName(entityClass);
    }
    
    // ==================== 基礎(chǔ)CRUD操作 ====================
    
    /**
     * 保存單個實(shí)體
     * 功能:保存或更新實(shí)體對象
     * 
     * 執(zhí)行邏輯:
     * 1. 如果實(shí)體對象包含_id字段且值不為空,則執(zhí)行更新操作(upsert)
     * 2. 如果實(shí)體對象不包含_id或_id為空,則執(zhí)行插入操作
     * 3. 插入成功后,MongoDB會自動生成ObjectId并賦值給_id字段
     * 
     * 使用場景:
     * - 新增數(shù)據(jù)時直接調(diào)用
     * - 修改數(shù)據(jù)時傳入包含_id的對象
     * 
     * @param entity 要保存的實(shí)體對象(必須包含@Document注解)
     * @return 保存后的實(shí)體對象(包含生成的_id)
     */
    public T save(T entity) {
        return mongoTemplate.save(entity);
    }
    
    /**
     * 批量保存實(shí)體
     * 功能:一次性保存多個實(shí)體對象,提高批量插入性能
     * 
     * 性能優(yōu)勢:
     * - 相比循環(huán)調(diào)用save()方法,批量操作可以減少網(wǎng)絡(luò)往返次數(shù)
     * - MongoDB支持批量插入,內(nèi)部優(yōu)化了寫入性能
     * 
     * 注意事項(xiàng):
     * - 如果數(shù)據(jù)量很大(如超過10000條),建議分批插入
     * - 如果其中某個文檔插入失敗,整個操作可能會回滾
     * 
     * @param entities 實(shí)體集合(List、Set等Collection類型)
     * @return 保存后的實(shí)體集合(包含生成的_id)
     */
    public List<T> saveBatch(Collection<T> entities) {
        return (List<T>) mongoTemplate.insertAll(entities);
    }
    
    /**
     * 插入單個實(shí)體
     * 功能:直接插入實(shí)體,不檢查是否已存在
     * 
     * 與save()的區(qū)別:
     * - save():智能判斷是插入還是更新(基于_id)
     * - insert():強(qiáng)制插入,如果_id已存在會拋出DuplicateKeyException異常
     * 
     * 使用場景:
     * - 確保不會重復(fù)插入時使用
     * - 需要明確區(qū)分新增和更新操作時使用
     * 
     * @param entity 要插入的實(shí)體對象
     * @return 插入后的實(shí)體對象
     * @throws org.springframework.dao.DuplicateKeyException 如果_id已存在
     */
    public T insert(T entity) {
        return mongoTemplate.insert(entity);
    }
    
    /**
     * 批量插入實(shí)體
     * 功能:批量插入到指定集合中,適合大量數(shù)據(jù)初始化
     * 
     * 使用說明:
     * - 通過entityClass參數(shù)指定目標(biāo)集合
     * - 相比saveBatch(),此方法可以明確指定集合名稱
     * 
     * @param entities 實(shí)體集合
     * @param entityClass 實(shí)體類類型(用于確定集合名稱)
     * @return 插入后的實(shí)體集合
     */
    public List<T> insertBatch(Collection<T> entities, Class<T> entityClass) {
        return (List<T>) mongoTemplate.insert(entities, entityClass);
    }
    
    /**
     * 根據(jù)ID查詢實(shí)體
     * 功能:通過MongoDB的文檔ID(_id字段)精確查詢單個文檔
     * 
     * 執(zhí)行邏輯:
     * 1. 構(gòu)造查詢條件:WHERE _id = ?
     * 2. 執(zhí)行查詢,返回匹配的第一個文檔
     * 3. 將文檔映射為Java實(shí)體對象
     * 
     * ID類型說明:
     * - MongoDB的_id默認(rèn)類型是ObjectId(24位十六進(jìn)制字符串)
     * - Spring Data MongoDB支持String、ObjectId、Long等多種類型
     * 
     * @param id 實(shí)體ID(通常是ObjectId類型或字符串)
     * @param entityClass 實(shí)體類類型(用于結(jié)果映射)
     * @return 查詢到的實(shí)體對象,不存在則返回null
     */
    public T findById(Object id, Class<T> entityClass) {
        return mongoTemplate.findById(id, entityClass);
    }
    
    /**
     * 查詢所有實(shí)體
     * 功能:查詢集合中的所有文檔
     * 
     * 性能警告:
     * - ?? 如果集合中數(shù)據(jù)量很大,此方法可能導(dǎo)致內(nèi)存溢出
     * - ?? 生產(chǎn)環(huán)境中謹(jǐn)慎使用,建議使用分頁查詢
     * 
     * 使用場景:
     * - 數(shù)據(jù)量小的配置表
     * - 數(shù)據(jù)導(dǎo)入導(dǎo)出操作
     * 
     * @param entityClass 實(shí)體類類型
     * @return 所有實(shí)體的列表
     */
    public List<T> findAll(Class<T> entityClass) {
        return mongoTemplate.findAll(entityClass);
    }
    
    /**
     * 根據(jù)條件查詢單個實(shí)體
     * 功能:根據(jù)自定義查詢條件返回第一個匹配的文檔
     * 
     * 執(zhí)行邏輯:
     * 1. 執(zhí)行傳入的查詢條件
     * 2. 只返回第一個匹配的文檔
     * 3. 如果沒有匹配文檔,返回null
     * 
     * 使用場景:
     * - 根據(jù)唯一鍵查詢(如用戶名、手機(jī)號)
     * - 獲取最新的一條記錄(配合排序)
     * 
     * @param query 查詢條件對象(通過Criteria構(gòu)造)
     * @param entityClass 實(shí)體類類型
     * @return 查詢到的實(shí)體對象,不存在則返回null
     */
    public T findOne(Query query, Class<T> entityClass) {
        return mongoTemplate.findOne(query, entityClass);
    }
    
    /**
     * 根據(jù)條件查詢實(shí)體列表
     * 功能:根據(jù)自定義查詢條件返回所有匹配的文檔
     * 
     * 執(zhí)行邏輯:
     * 1. 執(zhí)行傳入的查詢條件
     * 2. 返回所有匹配的文檔列表
     * 3. 如果沒有匹配文檔,返回空列表(不會返回null)
     * 
     * 使用場景:
     * - 條件查詢(如查詢某個狀態(tài)的所有用戶)
     * - 范圍查詢(如查詢某個時間段的所有訂單)
     * 
     * @param query 查詢條件對象(可以通過Criteria添加多個條件)
     * @param entityClass 實(shí)體類類型
     * @return 匹配的實(shí)體列表(可能為空列表)
     */
    public List<T> find(Query query, Class<T> entityClass) {
        return mongoTemplate.find(query, entityClass);
    }
    
    /**
     * 根據(jù)ID更新實(shí)體
     * 功能:根據(jù)文檔ID更新指定字段,只更新傳入的字段
     * 
     * 執(zhí)行邏輯:
     * 1. 構(gòu)造查詢條件:WHERE _id = ?
     * 2. 執(zhí)行更新操作,只修改Update對象中指定的字段
     * 3. 其他字段保持不變
     * 
     * 與save()的區(qū)別:
     * - save():會替換整個文檔(未傳入的字段會被清空)
     * - updateById():只更新指定字段(更安全,性能更好)
     * 
     * @param id 文檔ID(MongoDB的_id字段值)
     * @param update 更新操作對象(包含要更新的字段和新值)
     * @param entityClass 實(shí)體類類型
     * @return 更新結(jié)果對象,包含匹配數(shù)和修改數(shù)等信息
     */
    public UpdateResult updateById(Object id, Update update, Class<T> entityClass) {
        // 構(gòu)造查詢條件:ID等于傳入的id
        Query query = new Query(Criteria.where("_id").is(id));
        return mongoTemplate.updateFirst(query, update, entityClass);
    }
    
    /**
     * 根據(jù)條件更新第一個匹配的文檔
     * 功能:只更新查詢到的第一個文檔,即使有多個文檔匹配條件
     * 
     * 執(zhí)行邏輯:
     * 1. 根據(jù)query條件查找匹配的文檔
     * 2. 只更新第一個匹配的文檔
     * 3. 返回更新結(jié)果(包含影響的文檔數(shù))
     * 
     * 使用場景:
     * - 唯一鍵字段的更新
     * - 只需要更新一條記錄的情況
     * 
     * @param query 查詢條件對象(用于定位要更新的文檔)
     * @param update 更新操作對象(包含要更新的字段和新值)
     * @param entityClass 實(shí)體類類型
     * @return 更新結(jié)果對象,包含修改的文檔數(shù)等信息
     */
    public UpdateResult updateFirst(Query query, Update update, Class<T> entityClass) {
        return mongoTemplate.updateFirst(query, update, entityClass);
    }
    
    /**
     * 根據(jù)條件更新所有匹配的文檔
     * 功能:更新查詢條件匹配的所有文檔
     * 
     * 執(zhí)行邏輯:
     * 1. 根據(jù)query條件查找所有匹配的文檔
     * 2. 更新所有匹配的文檔
     * 3. 返回更新結(jié)果(包含影響的文檔數(shù))
     * 
     * 性能注意事項(xiàng):
     * - 如果匹配的文檔數(shù)量很多,此操作可能耗時較長
     * - 建議在查詢條件中添加索引以提高性能
     * 
     * 使用場景:
     * - 批量修改(如將所有狀態(tài)為0的用戶改為1)
     * - 數(shù)據(jù)修復(fù)和遷移
     * 
     * @param query 查詢條件對象(用于定位要更新的文檔)
     * @param update 更新操作對象(包含要更新的字段和新值)
     * @param entityClass 實(shí)體類類型
     * @return 更新結(jié)果對象,包含修改的文檔數(shù)等信息
     */
    public UpdateResult updateMulti(Query query, Update update, Class<T> entityClass) {
        return mongoTemplate.updateMulti(query, update, entityClass);
    }
    
    /**
     * 根據(jù)ID刪除實(shí)體
     * 功能:刪除指定ID的文檔
     * 
     * 執(zhí)行邏輯:
     * 1. 構(gòu)造查詢條件:WHERE _id = ?
     * 2. 執(zhí)行刪除操作
     * 3. 返回刪除結(jié)果(包含刪除的文檔數(shù))
     * 
     * 使用場景:
     * - 根據(jù)主鍵刪除單個文檔
     * - 物理刪除數(shù)據(jù)
     * 
     * @param id 文檔ID(MongoDB的_id字段值)
     * @param entityClass 實(shí)體類類型
     * @return 刪除結(jié)果對象,包含刪除的文檔數(shù)
     */
    public DeleteResult deleteById(Object id, Class<T> entityClass) {
        Query query = new Query(Criteria.where("_id").is(id));
        return mongoTemplate.remove(query, entityClass);
    }
    
    /**
     * 根據(jù)條件刪除實(shí)體
     * 功能:刪除查詢條件匹配的所有文檔
     * 
     * 執(zhí)行邏輯:
     * 1. 根據(jù)query條件查找所有匹配的文檔
     * 2. 刪除所有匹配的文檔
     * 3. 返回刪除結(jié)果(包含刪除的文檔數(shù))
     * 
     * ?? 安全警告:
     * - 如果query為空或條件太寬泛,會刪除大量數(shù)據(jù)
     * - 生產(chǎn)環(huán)境中務(wù)必仔細(xì)檢查查詢條件
     * 
     * @param query 查詢條件對象(用于定位要刪除的文檔)
     * @param entityClass 實(shí)體類類型
     * @return 刪除結(jié)果對象,包含刪除的文檔數(shù)
     */
    public DeleteResult delete(Query query, Class<T> entityClass) {
        return mongoTemplate.remove(query, entityClass);
    }
    
    /**
     * 刪除所有實(shí)體
     * 功能:清空整個集合中的所有文檔
     * 
     * ?? 危險操作:
     * - 此操作會刪除集合中的所有文檔
     * - 集合本身不會被刪除,但數(shù)據(jù)會全部清空
     * - 生產(chǎn)環(huán)境中謹(jǐn)慎使用,建議先備份數(shù)據(jù)
     * 
     * 使用場景:
     * - 測試數(shù)據(jù)清理
     * - 數(shù)據(jù)重置
     * 
     * @param entityClass 實(shí)體類類型
     * @return 刪除結(jié)果對象,包含刪除的文檔數(shù)
     */
    public DeleteResult deleteAll(Class<T> entityClass) {
        return mongoTemplate.remove(new Query(), entityClass);
    }
    
    /**
     * 檢查實(shí)體是否存在
     * 功能:檢查是否存在匹配查詢條件的文檔
     * 
     * 執(zhí)行邏輯:
     * 1. 根據(jù)query條件查詢
     * 2. 如果至少存在一個匹配文檔,返回true
     * 3. 如果沒有匹配文檔,返回false
     * 
     * 性能優(yōu)勢:
     * - 相比count(),此方法在找到第一個匹配文檔后立即返回
     * - 對于判斷存在性的場景,性能更好
     * 
     * 使用場景:
     * - 檢查用戶名是否已存在
     * - 檢查某個數(shù)據(jù)是否存在
     * 
     * @param query 查詢條件對象
     * @param entityClass 實(shí)體類類型
     * @return true表示存在,false表示不存在
     */
    public boolean exists(Query query, Class<T> entityClass) {
        return mongoTemplate.exists(query, entityClass);
    }
    
    /**
     * 統(tǒng)計(jì)文檔數(shù)量
     * 功能:統(tǒng)計(jì)匹配查詢條件的文檔總數(shù)
     * 
     * 執(zhí)行邏輯:
     * 1. 根據(jù)query條件查詢
     * 2. 統(tǒng)計(jì)所有匹配文檔的數(shù)量
     * 3. 返回總數(shù)(long類型)
     * 
     * 使用場景:
     * - 分頁查詢時先統(tǒng)計(jì)總數(shù)
     * - 數(shù)據(jù)統(tǒng)計(jì)報表
     * - 數(shù)據(jù)質(zhì)量檢查
     * 
     * 性能注意事項(xiàng):
     * - 在大表上執(zhí)行count()可能較慢
     * - 建議為查詢條件添加索引
     * 
     * @param query 查詢條件對象
     * @param entityClass 實(shí)體類類型
     * @return 文檔數(shù)量
     */
    public long count(Query query, Class<T> entityClass) {
        return mongoTemplate.count(query, entityClass);
    }
    
    // ==================== 分頁查詢 ====================
    
    /**
     * 分頁查詢
     * 功能:支持排序和分頁的綜合查詢方法
     * 
     * 執(zhí)行邏輯:
     * 1. 如果指定了排序字段,添加排序條件
     * 2. 先統(tǒng)計(jì)符合條件的總記錄數(shù)
     * 3. 根據(jù)頁碼和每頁大小計(jì)算skip和limit
     * 4. 執(zhí)行分頁查詢
     * 5. 構(gòu)造Spring Data的Page對象返回
     * 
     * 返回的Page對象包含:
     * - content:當(dāng)前頁的數(shù)據(jù)列表
     * - totalElements:總記錄數(shù)
     * - totalPages:總頁數(shù)
     * - currentPage:當(dāng)前頁碼
     * - hasNext/hasPrevious:是否有下一頁/上一頁
     * 
     * 性能優(yōu)化建議:
     * - 為排序字段和查詢條件字段添加索引
     * - 避免使用過大的skip值(深度分頁)
     * 
     * @param query 查詢條件對象(可以為空,表示查詢所有)
     * @param pageRequest 分頁參數(shù)對象(包含頁碼、每頁大小、排序信息)
     * @param entityClass 實(shí)體類類型
     * @return Spring Data的Page對象,包含數(shù)據(jù)和分頁信息
     */
    public Page<T> findPage(Query query, PageRequest pageRequest, Class<T> entityClass) {
        // 如果指定了排序字段,則添加排序條件
        if (pageRequest.getSortField() != null) {
            // 判斷排序方向:desc表示降序,否則為升序
            Sort.Direction direction = "desc".equalsIgnoreCase(pageRequest.getSortOrder()) 
                ? Sort.Direction.DESC : Sort.Direction.ASC;
            // 將排序條件添加到查詢對象中
            query.with(Sort.by(direction, pageRequest.getSortField()));
        }
        
        // 先統(tǒng)計(jì)總數(shù),用于分頁信息
        long total = mongoTemplate.count(query, entityClass);
        
        // 設(shè)置分頁參數(shù):跳過前N條數(shù)據(jù),然后限制返回?cái)?shù)量
        // skip: 跳過的記錄數(shù) = (頁碼-1) * 每頁大小
        // limit: 每頁返回的記錄數(shù)
        query.skip(pageRequest.getSkip()).limit(pageRequest.getPageSize());
        
        // 執(zhí)行分頁查詢
        List<T> list = mongoTemplate.find(query, entityClass);
        
        // 構(gòu)造Spring Data的Page對象返回
        return new PageImpl<>(list, 
            PageRequest.of(pageRequest.getPageNum() - 1, pageRequest.getPageSize()), 
            total);
    }
    
    // ==================== 高級查詢操作 ====================
    
    /**
     * 模糊查詢(不區(qū)分大小寫)
     * 功能:支持SQL LIKE '%keyword%'的模糊匹配,不區(qū)分大小寫
     * 
     * 實(shí)現(xiàn)原理:
     * 1. 使用正則表達(dá)式實(shí)現(xiàn)模糊匹配
     * 2. Pattern.CASE_INSENSITIVE標(biāo)志表示不區(qū)分大小寫
     * 3. MongoDB的$regex操作符支持正則表達(dá)式查詢
     * 
     * 性能注意事項(xiàng):
     * - 模糊查詢無法使用普通索引,只能全表掃描
     * - 在數(shù)據(jù)量大的情況下性能較差
     * - 建議配合其他條件縮小查詢范圍
     * 
     * 使用場景:
     * - 搜索功能(如搜索用戶名、商品名)
     * - 數(shù)據(jù)模糊匹配
     * 
     * @param fieldName 字段名(要搜索的字段)
     * @param keyword 關(guān)鍵詞(搜索的關(guān)鍵詞)
     * @return 查詢條件對象(Criteria)
     */
    public Criteria like(String fieldName, String keyword) {
        // 使用正則表達(dá)式實(shí)現(xiàn)模糊匹配,CASE_INSENSITIVE表示不區(qū)分大小寫
        Pattern pattern = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE);
        return Criteria.where(fieldName).regex(pattern);
    }
    
    /**
     * 多字段模糊查詢
     * 功能:在多個字段中搜索關(guān)鍵詞,任意一個字段匹配即滿足條件
     * 
     * 實(shí)現(xiàn)原理:
     * 1. 為每個字段構(gòu)造一個模糊查詢條件
     * 2. 使用OR操作符連接多個條件
     * 3. MongoDB的$or操作符實(shí)現(xiàn)OR邏輯
     * 
     * SQL等價:
     * WHERE field1 LIKE '%keyword%' OR field2 LIKE '%keyword%' OR ...
     * 
     * 使用場景:
     * - 全局搜索(同時搜索標(biāo)題、內(nèi)容、作者等)
     * - 多字段組合搜索
     * 
     * @param fields 字段名數(shù)組(要在哪些字段中搜索)
     * @param keyword 關(guān)鍵詞(搜索的關(guān)鍵詞)
     * @return 查詢條件對象(Criteria,使用OR連接)
     */
    public Criteria multiFieldLike(String[] fields, String keyword) {
        // 創(chuàng)建查詢條件數(shù)組,每個字段一個條件
        Criteria[] criteriaArray = new Criteria[fields.length];
        for (int i = 0; i < fields.length; i++) {
            criteriaArray[i] = like(fields[i], keyword);
        }
        // 使用orOperator將多個條件用OR連接
        return new Criteria().orOperator(criteriaArray);
    }
    
    /**
     * 范圍查詢
     * 功能:查詢字段值在指定范圍內(nèi)的文檔(包含邊界值)
     * 
     * 實(shí)現(xiàn)原理:
     * 1. gte: Greater Than or Equal(大于等于)
     * 2. lte: Less Than or Equal(小于等于)
     * 3. MongoDB的$gte和$lte操作符實(shí)現(xiàn)范圍查詢
     * 
     * SQL等價:
     * WHERE field >= min AND field <= max
     * 
     * 使用場景:
     * - 年齡范圍查詢(18-30歲)
     * - 價格范圍查詢(100-500元)
     * - 時間范圍查詢(某個時間段的數(shù)據(jù))
     * 
     * 性能優(yōu)化:
     * - 為范圍查詢字段添加索引可以顯著提高性能
     * - 復(fù)合索引:createIndex({field: 1})
     * 
     * @param fieldName 字段名(要進(jìn)行范圍查詢的字段)
     * @param min 最小值(包含)
     * @param max 最大值(包含)
     * @return 查詢條件對象(Criteria)
     */
    public Criteria between(String fieldName, Object min, Object max) {
        // gte: 大于等于,lte: 小于等于
        return Criteria.where(fieldName).gte(min).lte(max);
    }
    
    /**
     * 大于查詢
     * 功能:查詢字段值大于指定值的文檔
     * 
     * SQL等價:WHERE field > value
     * 
     * @param fieldName 字段名
     * @param value 比較值
     * @return 查詢條件對象(Criteria)
     */
    public Criteria gt(String fieldName, Object value) {
        return Criteria.where(fieldName).gt(value);
    }
    
    /**
     * 小于查詢
     * 功能:查詢字段值小于指定值的文檔
     * 
     * SQL等價:WHERE field < value
     * 
     * @param fieldName 字段名
     * @param value 比較值
     * @return 查詢條件對象(Criteria)
     */
    public Criteria lt(String fieldName, Object value) {
        return Criteria.where(fieldName).lt(value);
    }
    
    /**
     * 大于等于查詢
     * 功能:查詢字段值大于等于指定值的文檔
     * 
     * SQL等價:WHERE field >= value
     * 
     * @param fieldName 字段名
     * @param value 比較值
     * @return 查詢條件對象(Criteria)
     */
    public Criteria gte(String fieldName, Object value) {
        return Criteria.where(fieldName).gte(value);
    }
    
    /**
     * 小于等于查詢
     * 功能:查詢字段值小于等于指定值的文檔
     * 
     * SQL等價:WHERE field <= value
     * 
     * @param fieldName 字段名
     * @param value 比較值
     * @return 查詢條件對象(Criteria)
     */
    public Criteria lte(String fieldName, Object value) {
        return Criteria.where(fieldName).lte(value);
    }
    
    /**
     * 不等于查詢
     * 功能:查詢字段值不等于指定值的文檔
     * 
     * SQL等價:WHERE field <> value 或 WHERE field != value
     * 
     * 使用場景:
     * - 排除某個值
     * - 查詢非空值
     * 
     * @param fieldName 字段名
     * @param value 比較值
     * @return 查詢條件對象(Criteria)
     */
    public Criteria ne(String fieldName, Object value) {
        return Criteria.where(fieldName).ne(value);
    }
    
    /**
     * IN查詢
     * 功能:查詢字段值在指定值列表中的文檔
     * 
     * SQL等價:
     * WHERE field IN (value1, value2, value3, ...)
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$in操作符匹配數(shù)組中的任意一個值
     * - 適用于多選條件查詢
     * 
     * 使用場景:
     * - 多狀態(tài)查詢(如查詢狀態(tài)為0或1的用戶)
     * - ID列表查詢(根據(jù)多個ID查詢對應(yīng)的文檔)
     * - 標(biāo)簽查詢(查詢包含某些標(biāo)簽的文檔)
     * 
     * 性能優(yōu)化:
     * - 為IN查詢字段添加索引可以顯著提高性能
     * - IN列表長度不宜過長(建議不超過100個)
     * 
     * @param fieldName 字段名
     * @param values 值列表(Collection類型,如List、Set等)
     * @return 查詢條件對象(Criteria)
     */
    public Criteria in(String fieldName, Collection<?> values) {
        return Criteria.where(fieldName).in(values);
    }
    
    /**
     * NOT IN查詢
     * 功能:查詢字段值不在指定值列表中的文檔
     * 
     * SQL等價:
     * WHERE field NOT IN (value1, value2, value3, ...)
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$nin操作符匹配數(shù)組外的所有值
     * - 適用于排除多個值的場景
     * 
     * 使用場景:
     * - 排除多個狀態(tài)
     * - 排除某些特定值
     * 
     * 性能注意事項(xiàng):
     * - NOT IN查詢的性能通常低于IN查詢
     * - 大列表的NOT IN查詢可能較慢
     * 
     * @param fieldName 字段名
     * @param values 值列表(Collection類型)
     * @return 查詢條件對象(Criteria)
     */
    public Criteria notIn(String fieldName, Collection<?> values) {
        return Criteria.where(fieldName).nin(values);
    }
    
    /**
     * NULL查詢
     * 功能:查詢字段值為null的文檔
     * 
     * SQL等價:WHERE field IS NULL
     * 
     * 使用場景:
     * - 查找未填寫的字段
     * - 數(shù)據(jù)完整性檢查
     * 
     * @param fieldName 字段名
     * @return 查詢條件對象(Criteria)
     */
    public Criteria isNull(String fieldName) {
        return Criteria.where(fieldName).is(null);
    }
    
    /**
     * NOT NULL查詢
     * 功能:查詢字段值不為null的文檔
     * 
     * SQL等價:WHERE field IS NOT NULL
     * 
     * 使用場景:
     * - 查找已填寫的字段
     * - 過濾掉缺失的數(shù)據(jù)
     * 
     * @param fieldName 字段名
     * @return 查詢條件對象(Criteria)
     */
    public Criteria notNull(String fieldName) {
        return Criteria.where(fieldName).ne(null);
    }
    
    /**
     * 數(shù)組大小查詢
     * 功能:查詢數(shù)組字段長度等于指定值的文檔
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$size操作符用于查詢數(shù)組長度
     * - 只能匹配精確的數(shù)組長度,不能匹配范圍
     * 
     * 使用場景:
     * - 查詢標(biāo)簽數(shù)量(如查詢有3個標(biāo)簽的用戶)
     * - 查詢評論數(shù)量(如查詢有10條評論的文章)
     * 
     * 性能注意事項(xiàng):
     * - $size操作符無法使用普通索引
     * - 如果數(shù)據(jù)量大,考慮添加專門的索引
     * 
     * @param fieldName 字段名(必須是數(shù)組類型的字段)
     * @param size 數(shù)組大?。ň_匹配)
     * @return 查詢條件對象(Criteria)
     */
    public Criteria size(String fieldName, int size) {
        return Criteria.where(fieldName).size(size);
    }
    
    /**
     * 數(shù)組元素查詢
     * 功能:查詢數(shù)組字段中包含指定元素的文檔
     * 
     * 實(shí)現(xiàn)原理:
     * - 直接使用is()操作符查詢數(shù)組字段
     * - 如果數(shù)組中包含該元素,則匹配成功
     * 
     * 使用場景:
     * - 查詢包含某個標(biāo)簽的文檔
     * - 查詢包含某個值的數(shù)組
     * 
     * 示例:
     * - 查詢tags字段包含"java"的文檔:arrayContains("tags", "java")
     * 
     * @param fieldName 字段名(數(shù)組類型字段)
     * @param value 數(shù)組元素值(要在數(shù)組中查找的值)
     * @return 查詢條件對象(Criteria)
     */
    public Criteria arrayContains(String fieldName, Object value) {
        return Criteria.where(fieldName).is(value);
    }
    
    /**
     * 地理位置查詢 - 圓形范圍
     * 功能:查詢指定經(jīng)緯度坐標(biāo)附近指定范圍內(nèi)的文檔
     * 
     * 實(shí)現(xiàn)原理:
     * 1. 創(chuàng)建GeoJsonPoint對象存儲經(jīng)緯度
     * 2. 使用$nearSphere操作符進(jìn)行球面距離查詢
     * 3. maxDistance參數(shù)需要轉(zhuǎn)換為弧度(除以地球半徑)
     * 
     * 坐標(biāo)說明:
     * - 經(jīng)度:東西方向,范圍-180到180
     * - 緯度:南北方向,范圍-90到90
     * - 中國大致范圍:經(jīng)度73-135,緯度18-53
     * 
     * 距離計(jì)算:
     * - nearSphere使用球面距離計(jì)算(考慮地球曲率)
     * - 地球半徑:6378137米(赤道半徑)
     * - 轉(zhuǎn)換公式:弧度 = 距離(米) / 地球半徑(米)
     * 
     * 使用場景:
     * - 附近的人/商家/酒店查詢
     * - 地理位置相關(guān)的推薦
     * - 距離排序
     * 
     * 性能優(yōu)化:
     * - 必須為地理位置字段創(chuàng)建2dsphere索引
     * - 建議同時創(chuàng)建復(fù)合索引提高查詢性能
     * 
     * 示例:
     * - 查詢天安門(116.397, 39.918)附近1000米內(nèi)的地點(diǎn)
     * 
     * @param fieldName 字段名(存儲地理坐標(biāo)的字段,類型通常為GeoJsonPoint)
     * @param longitude 經(jīng)度(東西方向,-180到180)
     * @param latitude 緯度(南北方向,-90到90)
     * @param maxDistance 最大距離(單位:米)
     * @return 查詢條件對象(Criteria)
     */
    public Criteria nearSphere(String fieldName, double longitude, double latitude, double maxDistance) {
        // 創(chuàng)建地理坐標(biāo)點(diǎn)對象(經(jīng)度在前,緯度在后)
        Point point = new Point(longitude, latitude);
        
        // nearSphere使用球面距離計(jì)算,更精確(考慮地球曲率)
        // maxDistance需要除以地球半徑(6378137米)轉(zhuǎn)換為弧度
        // 因?yàn)镸ongoDB使用弧度作為距離單位
        return Criteria.where(fieldName).nearSphere(point).maxDistance(maxDistance / 6378137.0);
    }
    
    /**
     * 正則表達(dá)式查詢
     * 功能:支持使用正則表達(dá)式進(jìn)行靈活匹配
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$regex操作符支持PCRE正則表達(dá)式
     * - 支持復(fù)雜的字符串匹配模式
     * 
     * 常用正則表達(dá)式示例:
     * - ^abc: 以abc開頭
     * - abc$: 以abc結(jié)尾
     * - a.c: 中間是任意字符
     * - a*: 0個或多個a
     * - a+: 1個或多個a
     * - a?b: 可選的a后面跟著b
     * 
     * 使用場景:
     * - 復(fù)雜的字符串匹配
     * - 郵箱、手機(jī)號、身份證號驗(yàn)證
     * - 特定格式的數(shù)據(jù)查詢
     * 
     * 性能注意事項(xiàng):
     * - 正則查詢無法使用普通索引(除前綴匹配外)
     * - 復(fù)雜的正則表達(dá)式可能導(dǎo)致全表掃描
     * - 建議配合其他條件縮小查詢范圍
     * 
     * @param fieldName 字段名
     * @param pattern 正則表達(dá)式字符串(PCRE格式)
     * @return 查詢條件對象(Criteria)
     */
    public Criteria regex(String fieldName, String pattern) {
        return Criteria.where(fieldName).regex(pattern);
    }
    
    // ==================== 高級更新操作 ====================
    
    /**
     * 字段自增
     * 功能:將數(shù)值字段的值增加指定數(shù)量(支持正數(shù)和負(fù)數(shù))
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$inc操作符用于數(shù)值字段的原子自增/自減
     * - 原子操作:不需要先讀再寫,直接在數(shù)據(jù)庫端完成
     * 
     * 使用場景:
     * - 計(jì)數(shù)器(瀏覽量、點(diǎn)贊數(shù)、評論數(shù)等)
     * - 庫存扣減(減法操作)
     * - 積分增加(加法操作)
     * 
     * 優(yōu)勢:
     * - 原子操作,避免并發(fā)問題
     * - 性能優(yōu)于先讀后寫
     * - 支持小數(shù)運(yùn)算
     * 
     * 示例:
     * - increment("age", 1): 年齡加1
     * - increment("view_count", 100): 瀏覽量加100
     * - increment("stock", -5): 庫存減5
     * 
     * @param fieldName 字段名(必須是數(shù)值類型)
     * @param value 增量值(正數(shù)表示增加,負(fù)數(shù)表示減少)
     * @return 更新操作對象(Update)
     */
    public Update increment(String fieldName, Number value) {
        return new Update().inc(fieldName, value);
    }
    
    /**
     * 字段自乘
     * 功能:將數(shù)值字段的值乘以指定倍數(shù)
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$mul操作符用于數(shù)值字段的乘法運(yùn)算
     * - 原子操作,避免并發(fā)問題
     * 
     * 使用場景:
     * - 價格調(diào)整(打折扣)
     * - 權(quán)重計(jì)算
     * - 比例調(diào)整
     * 
     * 示例:
     * - multiply("price", 0.9): 價格打9折
     * - multiply("quantity", 2): 數(shù)量翻倍
     * 
     * @param fieldName 字段名(必須是數(shù)值類型)
     * @param value 乘數(shù)(乘數(shù))
     * @return 更新操作對象(Update)
     */
    public Update multiply(String fieldName, Number value) {
        return new Update().mul(fieldName, value);
    }
    
    /**
     * 數(shù)組添加元素
     * 功能:向數(shù)組字段添加一個元素(如果數(shù)組不存在則創(chuàng)建)
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$push操作符用于向數(shù)組添加元素
     * - 如果字段不存在,會自動創(chuàng)建并添加元素
     * - 如果字段存在但不是數(shù)組,會報錯
     * 
     * 使用場景:
     * - 添加標(biāo)簽
     * - 添加評論
     * - 添加收藏項(xiàng)
     * 
     * 示例:
     * - push("tags", "java"): 向tags數(shù)組添加"java"
     * 
     * 注意事項(xiàng):
     * - 此方法會在數(shù)組末尾添加元素
     * - 如果要添加多個元素,使用pushAll()
     * - 如果要避免重復(fù)元素,使用$addToSet(Spring Data MongoDB默認(rèn))
     * 
     * @param fieldName 字段名(數(shù)組類型字段)
     * @param value 要添加的元素值
     * @return 更新操作對象(Update)
     */
    public Update push(String fieldName, Object value) {
        return new Update().push(fieldName, value);
    }
    
    /**
     * 數(shù)組批量添加元素
     * 功能:向數(shù)組字段一次性添加多個元素
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$pushAll操作符用于批量添加數(shù)組元素
     * - 一次操作添加多個元素,提高性能
     * 
     * 使用場景:
     * - 批量添加標(biāo)簽
     * - 批量添加列表項(xiàng)
     * 
     * 性能優(yōu)勢:
     * - 相比循環(huán)調(diào)用push(),此方法性能更好
     * - 減少網(wǎng)絡(luò)往返次數(shù)
     * 
     * @param fieldName 字段名(數(shù)組類型字段)
     * @param values 要添加的元素?cái)?shù)組
     * @return 更新操作對象(Update)
     */
    public Update pushAll(String fieldName, Object[] values) {
        return new Update().pushAll(fieldName, values);
    }
    
    /**
     * 數(shù)組刪除元素
     * 功能:從數(shù)組字段中刪除指定值的所有匹配項(xiàng)
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$pull操作符用于刪除數(shù)組中匹配的元素
     * - 如果有多個相同的值,都會被刪除
     * - 如果值不存在,不會報錯
     * 
     * 使用場景:
     * - 刪除標(biāo)簽
     * - 刪除評論
     * - 刪除列表項(xiàng)
     * 
     * 示例:
     * - pull("tags", "java"): 從tags數(shù)組刪除所有"java"
     * 
     * @param fieldName 字段名(數(shù)組類型字段)
     * @param value 要刪除的元素值
     * @return 更新操作對象(Update)
     */
    public Update pull(String fieldName, Object value) {
        return new Update().pull(fieldName, value);
    }
    
    /**
     * 數(shù)組刪除多個元素
     * 功能:從數(shù)組字段中批量刪除指定的多個元素
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$pullAll操作符用于批量刪除數(shù)組元素
     * - 一次操作刪除多個元素,提高性能
     * 
     * 使用場景:
     * - 批量刪除標(biāo)簽
     * - 批量刪除列表項(xiàng)
     * 
     * @param fieldName 字段名(數(shù)組類型字段)
     * @param values 要刪除的元素?cái)?shù)組
     * @return 更新操作對象(Update)
     */
    public Update pullAll(String fieldName, Object[] values) {
        return new Update().pullAll(fieldName, values);
    }
    
    /**
     * 修改數(shù)組中指定位置的元素
     * 功能:使用位置運(yùn)算符更新數(shù)組中特定位置的元素
     * 
     * 實(shí)現(xiàn)原理:
     * - 使用$set操作符更新指定位置的數(shù)組元素
     * - 需要配合查詢條件確定數(shù)組索引
     * 
     * 使用方式:
     * 1. 使用字段名加索引的方式指定位置,如"tags.0"表示第一個元素
     * 2. 可以配合查詢條件使用,如"tags.$.value"(使用$表示匹配的元素)
     * 
     * 使用場景:
     * - 修改數(shù)組中特定位置的元素
     * - 配合$elemMatch使用
     * 
     * 示例:
     * - setAtIndex("tags.0", "python"): 修改tags數(shù)組的第一個元素為"python"
     * 
     * 注意事項(xiàng):
     * - 直接指定索引時,需要確保索引在數(shù)組范圍內(nèi)
     * - 建議配合查詢條件使用更安全
     * 
     * @param fieldName 字段名(包含位置表達(dá)式,如"tags.0"或使用$運(yùn)算符)
     * @param value 新的元素值
     * @return 更新操作對象(Update)
     */
    public Update setAtIndex(String fieldName, Object value) {
        return new Update().set(fieldName, value);
    }
    
    /**
     * 如果字段不存在則設(shè)置
     * 功能:僅在插入新文檔時設(shè)置字段值,更新時不會覆蓋已存在的字段
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$setOnInsert操作符
     * - 只在文檔不存在(即插入新文檔)時設(shè)置字段
     * - 如果文檔已存在(即更新操作),此字段不會被修改
     * 
     * 使用場景:
     * - 設(shè)置創(chuàng)建時間(只在創(chuàng)建時設(shè)置,更新時不修改)
     * - 設(shè)置默認(rèn)值(只在首次創(chuàng)建時設(shè)置)
     * - 設(shè)置初始化標(biāo)志
     * 
     * 示例:
     * - setOnInsert("create_time", new Date()): 只在插入時設(shè)置創(chuàng)建時間
     * - setOnInsert("version", 1): 只在插入時設(shè)置初始版本號
     * 
     * 注意事項(xiàng):
     * - 通常與upsert操作配合使用
     * - 如果不使用upsert,此操作無意義
     * 
     * @param fieldName 字段名
     * @param value 字段值
     * @return 更新操作對象(Update)
     */
    public Update setOnInsert(String fieldName, Object value) {
        return new Update().setOnInsert(fieldName, value);
    }
    
    /**
     * 重命名字段
     * 功能:將文檔中的字段重命名
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$rename操作符
     * - 原子操作,不需要先讀后寫
     * 
     * 使用場景:
     * - 字段名優(yōu)化(如將old_name改為newName)
     * - 數(shù)據(jù)結(jié)構(gòu)遷移
     * - 字段名規(guī)范化
     * 
     * 示例:
     * - rename("username", "user_name"): 將username字段重命名為user_name
     * 
     * 注意事項(xiàng):
     * - 如果新字段名已存在,會被覆蓋
     * - 如果舊字段名不存在,不會有任何效果
     * - 此操作在大型集合上可能較慢
     * 
     * @param oldName 舊字段名
     * @param newName 新字段名
     * @return 更新操作對象(Update)
     */
    public Update rename(String oldName, String newName) {
        return new Update().rename(oldName, newName);
    }
    
    /**
     * 刪除字段
     * 功能:從文檔中刪除指定字段
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$unset操作符
     * - 原子操作,不需要先讀后寫
     * 
     * 使用場景:
     * - 數(shù)據(jù)清理(刪除不需要的字段)
     * - 敏感信息刪除
     * - 數(shù)據(jù)結(jié)構(gòu)優(yōu)化
     * 
     * 示例:
     * - unset("password"): 刪除password字段
     * - unset("temporary_field"): 刪除臨時字段
     * 
     * 注意事項(xiàng):
     * - 如果字段不存在,不會有任何效果(不會報錯)
     * - 刪除操作是永久的,無法恢復(fù)
     * 
     * @param fieldName 字段名
     * @return 更新操作對象(Update)
     */
    public Update unset(String fieldName) {
        return new Update().unset(fieldName);
    }
    
    /**
     * 當(dāng)前時間更新
     * 功能:將指定字段更新為當(dāng)前日期時間
     * 
     * 實(shí)現(xiàn)原理:
     * - MongoDB的$currentDate操作符
     * - 使用服務(wù)器當(dāng)前時間
     * - 原子操作,不需要先讀后寫
     * 
     * 使用場景:
     * - 更新時間戳(最后修改時間)
     * - 記錄更新時間
     * - 審計(jì)日志
     * 
     * 示例:
     * - currentDate("update_time"): 將update_time字段更新為當(dāng)前時間
     * - currentDate("last_modified"): 將last_modified字段更新為當(dāng)前時間
     * 
     * 優(yōu)勢:
     * - 不需要在Java代碼中獲取時間
     * - 避免客戶端和服務(wù)器時間不一致的問題
     * - 性能優(yōu)于先讀后寫
     * 
     * @param fieldName 字段名(通常是日期或時間戳類型)
     * @return 更新操作對象(Update)
     */
    public Update currentDate(String fieldName) {
        return new Update().currentDate(fieldName);
    }
    
    // ==================== 聚合操作 ====================
    
    /**
     * 執(zhí)行聚合查詢
     * 功能:執(zhí)行自定義的聚合管道,支持復(fù)雜的數(shù)據(jù)處理和統(tǒng)計(jì)
     * 
     * 聚合管道概念:
     * - 聚合管道是MongoDB強(qiáng)大的數(shù)據(jù)處理功能
     * - 通過多個階段(stage)依次處理數(shù)據(jù)
     * - 每個階段接收上階段的輸出作為輸入
     * 
     * 常用聚合階段:
     * - $match: 過濾文檔(類似WHERE)
     * - $group: 分組統(tǒng)計(jì)(類似GROUP BY)
     * - $sort: 排序(類似ORDER BY)
     * - $project: 投影(選擇字段)
     * - $limit: 限制返回?cái)?shù)量
     * - $skip: 跳過指定數(shù)量
     * - $lookup: 關(guān)聯(lián)查詢(類似JOIN)
     * - $unwind: 拆分?jǐn)?shù)組
     * 
     * 使用場景:
     * - 復(fù)雜的數(shù)據(jù)統(tǒng)計(jì)
     * - 數(shù)據(jù)報表生成
     * - 數(shù)據(jù)分析
     * - 數(shù)據(jù)關(guān)聯(lián)查詢
     * 
     * 性能優(yōu)化:
     * - 盡早使用$match過濾數(shù)據(jù)
     * - 為查詢字段添加索引
     * - 合理使用投影減少數(shù)據(jù)傳輸量
     * 
     * @param aggregation 聚合操作對象(包含多個聚合階段)
     * @param entityClass 實(shí)體類類型(輸入類型)
     * @return 聚合結(jié)果對象(包含映射結(jié)果)
     */
    public AggregationResults<T> aggregate(Aggregation aggregation, Class<T> entityClass) {
        return mongoTemplate.aggregate(aggregation, entityClass, entityClass);
    }
    
    /**
     * 分組計(jì)數(shù)
     * 功能:按指定字段分組,統(tǒng)計(jì)每組的文檔數(shù)量
     * 
     * SQL等價:
     * SELECT field, COUNT(*) as count FROM table GROUP BY field ORDER BY count DESC
     * 
     * 聚合管道:
     * 1. $group: 按指定字段分組,使用count()統(tǒng)計(jì)數(shù)量
     * 2. $sort: 按計(jì)數(shù)降序排序
     * 
     * 使用場景:
     * - 統(tǒng)計(jì)各分類下的文章數(shù)量
     * - 統(tǒng)計(jì)各狀態(tài)的用戶數(shù)量
     * - 統(tǒng)計(jì)各個地區(qū)的訂單數(shù)量
     * 
     * 返回結(jié)果:
     * - List<Map>,每個Map包含:
     *   - _id: 分組字段的值
     *   - count: 文檔數(shù)量
     * 
     * @param groupByField 分組字段名(要按哪個字段分組)
     * @param entityClass 實(shí)體類類型
     * @return 分組統(tǒng)計(jì)結(jié)果列表(每項(xiàng)包含字段值和計(jì)數(shù))
     */
    public List<Map> groupCount(String groupByField, Class<T> entityClass) {
        // 構(gòu)建聚合管道:
        // 1. $group: 按指定字段分組,并統(tǒng)計(jì)每組的文檔數(shù)
        // 2. $sort: 按計(jì)數(shù)降序排序
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.group(groupByField).count().as("count"),
            Aggregation.sort(Sort.Direction.DESC, "count")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(
            aggregation, entityClass, Map.class);
        return results.getMappedResults();
    }
    
    /**
     * 分組求和
     * 功能:按指定字段分組,計(jì)算每組的數(shù)值字段總和
     * 
     * SQL等價:
     * SELECT field, SUM(num_field) as total FROM table GROUP BY field ORDER BY total DESC
     * 
     * 聚合管道:
     * 1. $group: 按指定字段分組,使用sum()求和
     * 2. $sort: 按總和降序排序
     * 
     * 使用場景:
     * - 統(tǒng)計(jì)各分類的總銷售額
     * - 統(tǒng)計(jì)各部門的總支出
     * - 統(tǒng)計(jì)各用戶的總消費(fèi)
     * 
     * 返回結(jié)果:
     * - List<Map>,每個Map包含:
     *   - _id: 分組字段的值
     *   - total: 總和
     * 
     * @param groupByField 分組字段名
     * @param sumField 要求和的數(shù)值字段名
     * @param entityClass 實(shí)體類類型
     * @return 分組求和結(jié)果列表
     */
    public List<Map> groupSum(String groupByField, String sumField, Class<T> entityClass) {
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.group(groupByField).sum(sumField).as("total"),
            Aggregation.sort(Sort.Direction.DESC, "total")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(
            aggregation, entityClass, Map.class);
        return results.getMappedResults();
    }
    
    /**
     * 分組求平均值
     * 功能:按指定字段分組,計(jì)算每組的數(shù)值字段平均值
     * 
     * SQL等價:
     * SELECT field, AVG(num_field) as average FROM table GROUP BY field ORDER BY average DESC
     * 
     * 聚合管道:
     * 1. $group: 按指定字段分組,使用avg()求平均
     * 2. $sort: 按平均值降序排序
     * 
     * 使用場景:
     * - 統(tǒng)計(jì)各分類的平均價格
     * - 統(tǒng)計(jì)各班級的平均分
     * - 統(tǒng)計(jì)各員工的平均績效
     * 
     * 返回結(jié)果:
     * - List<Map>,每個Map包含:
     *   - _id: 分組字段的值
     *   - average: 平均值
     * 
     * @param groupByField 分組字段名
     * @param avgField 要求平均的數(shù)值字段名
     * @param entityClass 實(shí)體類類型
     * @return 分組求平均結(jié)果列表
     */
    public List<Map> groupAvg(String groupByField, String avgField, Class<T> entityClass) {
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.group(groupByField).avg(avgField).as("average"),
            Aggregation.sort(Sort.Direction.DESC, "average")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(
            aggregation, entityClass, Map.class);
        return results.getMappedResults();
    }
    
    /**
     * 聚合分頁查詢
     * 功能:對聚合查詢結(jié)果進(jìn)行分頁,支持統(tǒng)計(jì)總數(shù)和返回分頁數(shù)據(jù)
     * 
     * 實(shí)現(xiàn)難點(diǎn):
     * - 聚合查詢的分頁需要執(zhí)行兩次聚合
     * - 第一次:統(tǒng)計(jì)總數(shù)(使用$count)
     * - 第二次:分頁查詢(使用$skip和$limit)
     * 
     * 執(zhí)行邏輯:
     * 1. 如果指定了排序,添加排序階段
     * 2. 第一次聚合:統(tǒng)計(jì)總數(shù)
     * 3. 第二次聚合:執(zhí)行分頁查詢
     * 4. 構(gòu)造Page對象返回
     * 
     * 性能優(yōu)化:
     * - 兩次聚合可能影響性能
     * - 考慮使用緩存優(yōu)化
     * - 對于大數(shù)據(jù)集,考慮使用游標(biāo)分頁
     * 
     * @param aggregation 聚合操作對象
     * @param pageRequest 分頁參數(shù)對象
     * @param entityClass 實(shí)體類類型
     * @return 分頁結(jié)果對象(Page接口)
     */
    public Page<T> aggregatePage(Aggregation aggregation, PageRequest pageRequest, 
                                Class<T> entityClass) {
        // 如果指定了排序字段,添加排序條件
        if (pageRequest.getSortField() != null) {
            Sort.Direction direction = "desc".equalsIgnoreCase(pageRequest.getSortOrder()) 
                ? Sort.Direction.DESC : Sort.Direction.ASC;
            // 在原有聚合操作基礎(chǔ)上追加排序階段
            aggregation = Aggregation.newAggregation(
                aggregation.getOperations(),
                Aggregation.sort(Sort.by(direction, pageRequest.getSortField()))
            );
        }
        
        // 第一次聚合:統(tǒng)計(jì)總數(shù)
        // 在聚合管道末尾添加$count階段
        Aggregation countAggregation = Aggregation.newAggregation(
            aggregation.getOperations(),
            Aggregation.count().as("total")
        );
        AggregationResults<Map> countResults = mongoTemplate.aggregate(
            countAggregation, entityClass, Map.class);
        // 提取總數(shù),如果沒有結(jié)果則為0
        long total = countResults.getMappedResults().isEmpty() ? 0 : 
            (Long) countResults.getMappedResults().get(0).get("total");
        
        // 第二次聚合:執(zhí)行分頁查詢
        // 在聚合管道末尾添加$skip和$limit階段
        Aggregation pageAggregation = Aggregation.newAggregation(
            aggregation.getOperations(),
            Aggregation.skip(pageRequest.getSkip()),
            Aggregation.limit(pageRequest.getPageSize())
        );
        AggregationResults<T> results = mongoTemplate.aggregate(
            pageAggregation, entityClass, entityClass);
        
        // 構(gòu)造并返回Page對象
        return new PageImpl<>(results.getMappedResults(), 
            PageRequest.of(pageRequest.getPageNum() - 1, pageRequest.getPageSize()), 
            total);
    }
    
    /**
     * 查找最大值
     * 功能:查詢指定字段的最大值
     * 
     * SQL等價:SELECT MAX(field) as maxValue FROM table
     * 
     * 聚合管道:
     * - $group: 不分組(使用空的group()),使用max()求最大值
     * 
     * 使用場景:
     * - 查找最高價格
     * - 查找最大年齡
     * - 查找最新時間
     * 
     * @param fieldName 字段名(必須是數(shù)值或日期類型)
     * @param entityClass 實(shí)體類類型
     * @return 最大值對象(如果沒有數(shù)據(jù)則返回null)
     */
    public Object max(String fieldName, Class<T> entityClass) {
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.group().max(fieldName).as("maxValue")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(
            aggregation, entityClass, Map.class);
        return results.getMappedResults().isEmpty() ? null : 
            results.getMappedResults().get(0).get("maxValue");
    }
    
    /**
     * 查找最小值
     * 功能:查詢指定字段的最小值
     * 
     * SQL等價:SELECT MIN(field) as minValue FROM table
     * 
     * 聚合管道:
     * - $group: 不分組(使用空的group()),使用min()求最小值
     * 
     * 使用場景:
     * - 查找最低價格
     * - 查找最小年齡
     * - 查找最早時間
     * 
     * @param fieldName 字段名(必須是數(shù)值或日期類型)
     * @param entityClass 實(shí)體類類型
     * @return 最小值對象(如果沒有數(shù)據(jù)則返回null)
     */
    public Object min(String fieldName, Class<T> entityClass) {
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.group().min(fieldName).as("minValue")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(
            aggregation, entityClass, Map.class);
        return results.getMappedResults().isEmpty() ? null : 
            results.getMappedResults().get(0).get("minValue");
    }
    
    /**
     * 查找平均值
     * 功能:查詢指定字段的平均值
     * 
     * SQL等價:SELECT AVG(field) as avgValue FROM table
     * 
     * 聚合管道:
     * - $group: 不分組(使用空的group()),使用avg()求平均值
     * 
     * 使用場景:
     * - 計(jì)算平均價格
     * - 計(jì)算平均年齡
     * - 計(jì)算平均分
     * 
     * @param fieldName 字段名(必須是數(shù)值類型)
     * @param entityClass 實(shí)體類類型
     * @return 平均值(Double類型,如果沒有數(shù)據(jù)則返回null)
     */
    public Double avg(String fieldName, Class<T> entityClass) {
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.group().avg(fieldName).as("avgValue")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(
            aggregation, entityClass, Map.class);
        return results.getMappedResults().isEmpty() ? null : 
            (Double) results.getMappedResults().get(0).get("avgValue");
    }
    
    /**
     * 求和
     * 功能:查詢指定字段的總和
     * 
     * SQL等價:SELECT SUM(field) as sumValue FROM table
     * 
     * 聚合管道:
     * - $group: 不分組(使用空的group()),使用sum()求和
     * 
     * 使用場景:
     * - 計(jì)算總銷售額
     * - 計(jì)算總數(shù)量
     * - 計(jì)算總積分
     * 
     * @param fieldName 字段名(必須是數(shù)值類型)
     * @param entityClass 實(shí)體類類型
     * @return 總和(Double類型,如果沒有數(shù)據(jù)則返回null)
     */
    public Double sum(String fieldName, Class<T> entityClass) {
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.group().sum(fieldName).as("sumValue")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(
            aggregation, entityClass, Map.class);
        return results.getMappedResults().isEmpty() ? null : 
            ((Number) results.getMappedResults().get(0).get("sumValue")).doubleValue();
    }
    
    // ==================== 事務(wù)處理 ====================
    
    /**
     * 執(zhí)行事務(wù)操作(無返回值)
     * 功能:在事務(wù)中執(zhí)行操作,發(fā)生異常時自動回滾
     * 
     * MongoDB事務(wù)特性:
     * - 需要MongoDB 4.0+版本
     * - 需要副本集環(huán)境(Replica Set)
     * - 支持ACID特性(原子性、一致性、隔離性、持久性)
     * - 同一事務(wù)內(nèi)只能操作同一個數(shù)據(jù)庫
     * 
     * 使用場景:
     * - 轉(zhuǎn)賬操作(涉及兩個賬戶)
     * - 訂單處理(訂單、庫存、日志同時更新)
     * - 多步操作需要保證數(shù)據(jù)一致性
     * 
     * 性能注意事項(xiàng):
     * - 事務(wù)操作會降低性能
     * - 事務(wù)執(zhí)行時間不宜過長(建議不超過60秒)
     * - 避免在事務(wù)中執(zhí)行大量查詢
     * 
     * 示例:
     * ```java
     * mongoUtils.executeInTransaction(() -> {
     *     // 扣減余額
     *     updateBalance(fromId, -100);
     *     // 增加余額
     *     updateBalance(toId, 100);
     * });
     * ```
     * 
     * @param action 要執(zhí)行的操作(Runnable接口,無返回值)
     * @return 操作是否成功(成功返回true,拋出異常返回false)
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean executeInTransaction(Runnable action) {
        try {
            // 執(zhí)行事務(wù)內(nèi)的操作
            action.run();
            // 如果沒有異常,返回true表示成功
            return true;
        } catch (Exception e) {
            // 記錄錯誤日志
            log.error("事務(wù)執(zhí)行失敗", e);
            // 重新拋出異常以觸發(fā)事務(wù)回滾
            throw e;
        }
    }
    
    /**
     * 執(zhí)行事務(wù)操作并返回結(jié)果
     * 功能:在事務(wù)中執(zhí)行有返回值的操作,發(fā)生異常時自動回滾
     * 
     * 與executeInTransaction()的區(qū)別:
     * - 此方法可以返回操作結(jié)果
     * - 使用Supplier接口(有返回值)
     * - 適用于需要獲取操作結(jié)果的場景
     * 
     * 使用場景:
     * - 創(chuàng)建對象并返回ID
     * - 執(zhí)行計(jì)算并返回結(jié)果
     * - 任何需要返回值的事務(wù)操作
     * 
     * 示例:
     * ```java
     * User user = mongoUtils.executeInTransactionWithResult(() -> {
     *     // 創(chuàng)建用戶
     *     return saveUser(user);
     *     // 創(chuàng)建關(guān)聯(lián)數(shù)據(jù)
     *     saveProfile(profile);
     * });
     * ```
     * 
     * @param action 要執(zhí)行的操作(Supplier接口,有返回值)
     * @param <R> 返回值類型
     * @return 操作結(jié)果
     * @throws RuntimeException 如果事務(wù)執(zhí)行失敗,拋出異常觸發(fā)回滾
     */
    @Transactional(rollbackFor = Exception.class)
    public <R> R executeInTransactionWithResult(java.util.function.Supplier<R> action) {
        try {
            // 執(zhí)行事務(wù)內(nèi)的操作并返回結(jié)果
            return action.get();
        } catch (Exception e) {
            // 記錄錯誤日志
            log.error("事務(wù)執(zhí)行失敗", e);
            // 重新拋出異常以觸發(fā)事務(wù)回滾
            throw e;
        }
    }
    
    // ==================== 索引操作 ====================
    
    /**
     * 創(chuàng)建索引
     * 功能:根據(jù)實(shí)體類上的@Indexed注解創(chuàng)建索引
     * 
     * 索引類型:
     * - 單字段索引:createIndex({field: 1})
     * - 復(fù)合索引:createIndex({field1: 1, field2: -1})
     * - 唯一索引:@Indexed(unique = true)
     * - 過期索引:@Indexed(expireAfterSeconds = 3600)
     * - 地理索引:@GeoSpatialIndexed
     * 
     * 性能影響:
     * - 索引會提高查詢性能
     * - 索引會降低插入、更新、刪除性能
     * - 索引占用磁盤空間
     * 
     * 最佳實(shí)踐:
     * - 為常用查詢字段創(chuàng)建索引
     * - 避免過度索引
     * - 定期分析慢查詢,優(yōu)化索引
     * 
     * @param entityClass 實(shí)體類類型(包含@Indexed注解)
     */
    public void createIndex(Class<T> entityClass) {
        mongoTemplate.indexOps(entityClass).ensureIndexes();
    }
    
    /**
     * 刪除索引
     * 功能:刪除集合的所有索引(保留_id索引)
     * 
     * 注意事項(xiàng):
     * - _id索引無法被刪除(MongoDB默認(rèn)索引)
     * - 刪除索引后,相關(guān)查詢性能會下降
     * - 生產(chǎn)環(huán)境中謹(jǐn)慎使用
     * 
     * 使用場景:
     * - 重建索引(刪除后重新創(chuàng)建)
     * - 數(shù)據(jù)遷移
     * - 性能測試
     * 
     * @param entityClass 實(shí)體類類型
     */
    public void dropIndex(Class<T> entityClass) {
        mongoTemplate.indexOps(entityClass).dropAllIndexes();
    }
    
    /**
     * 獲取所有索引
     * 功能:查詢集合的所有索引信息
     * 
     * 返回信息:
     * - 索引名稱
     * - 索引字段
     * - 索引類型(單字段、復(fù)合、唯一等)
     * - 索引大小
     * 
     * 使用場景:
     * - 檢查索引創(chuàng)建情況
     * - 性能分析
     * - 索引優(yōu)化
     * 
     * @param entityClass 實(shí)體類類型
     * @return 索引信息列表(IndexInfo對象列表)
     */
    public List<IndexInfo> getIndexes(Class<T> entityClass) {
        return mongoTemplate.indexOps(entityClass).getIndexInfo();
    }
    
    // ==================== 批量操作 ====================
    
    /**
     * 批量插入
     * 功能:批量插入多個文檔
     * 
     * 性能優(yōu)勢:
     * - 減少網(wǎng)絡(luò)往返次數(shù)
     * - MongoDB內(nèi)部優(yōu)化批量寫入
     * 
     * 使用場景:
     * - 數(shù)據(jù)初始化
     * - 數(shù)據(jù)導(dǎo)入
     * - 批量新增
     * 
     * @param entities 實(shí)體集合
     * @param entityClass 實(shí)體類類型
     * @return 插入的實(shí)體集合
     */
    public List<T> bulkInsert(Collection<T> entities, Class<T> entityClass) {
        return (List<T>) mongoTemplate.insertAll(entities);
    }
    
    /**
     * 批量更新
     * 功能:執(zhí)行多個更新操作,一次性提交,提高性能
     * 
     * 實(shí)現(xiàn)原理:
     * - 使用BulkOperations進(jìn)行批量操作
     * - UNORDERED模式:無序執(zhí)行,效率更高
     * - 一次性提交所有更新操作
     * 
     * 性能優(yōu)勢:
     * - 減少網(wǎng)絡(luò)往返次數(shù)
     * - MongoDB內(nèi)部優(yōu)化批量執(zhí)行
     * - 顯著提高大量更新的性能
     * 
     * 使用場景:
     * - 批量修改數(shù)據(jù)
     * - 數(shù)據(jù)修復(fù)
     * - 批量更新狀態(tài)
     * 
     * 示例:
     * ```java
     * List<BulkUpdateOperation> updates = new ArrayList<>();
     * updates.add(new BulkUpdateOperation(query1, update1));
     * updates.add(new BulkUpdateOperation(query2, update2));
     * BulkOperationsResult result = bulkUpdate(updates, User.class);
     * ```
     * 
     * @param updates 更新操作列表(每個元素包含查詢條件和更新內(nèi)容)
     * @param entityClass 實(shí)體類類型
     * @return 批量操作結(jié)果(包含插入、修改、刪除的文檔數(shù))
     */
    public BulkOperationsResult bulkUpdate(List<BulkUpdateOperation> updates, Class<T> entityClass) {
        // 創(chuàng)建批量操作對象,使用UNORDERED模式(無序執(zhí)行,效率更高)
        // UNORDERED: 并發(fā)執(zhí)行,速度快但錯誤處理復(fù)雜
        // ORDERED: 順序執(zhí)行,遇到錯誤停止,速度較慢
        BulkOperations bulkOps = mongoTemplate.bulkOps(
            BulkOperations.BulkMode.UNORDERED, entityClass);
        
        // 將每個更新操作添加到批量操作中
        for (BulkUpdateOperation update : updates) {
            bulkOps.updateOne(update.getQuery(), update.getUpdate());
        }
        
        // 執(zhí)行批量操作并獲取結(jié)果
        com.mongodb.client.result.BulkWriteResult result = bulkOps.execute();
        // 封裝并返回批量操作結(jié)果
        return new BulkOperationsResult(
            result.getInsertedCount(),
            result.getModifiedCount(),
            result.getDeletedCount()
        );
    }
    
    /**
     * 批量操作結(jié)果封裝類
     * 功能:封裝批量操作的執(zhí)行結(jié)果,方便調(diào)用方獲取操作統(tǒng)計(jì)信息
     * 
     * 包含信息:
     * - insertedCount: 插入的文檔數(shù)
     * - modifiedCount: 修改的文檔數(shù)
     * - deletedCount: 刪除的文檔數(shù)
     * 
     * 使用場景:
     * - 統(tǒng)計(jì)批量操作的影響范圍
     * - 日志記錄
     * - 操作驗(yàn)證
     */
    @Data
    public static class BulkOperationsResult {
        // 插入的文檔數(shù)
        private long insertedCount;
        // 修改的文檔數(shù)
        private long modifiedCount;
        // 刪除的文檔數(shù)
        private long deletedCount;
        
        /**
         * 構(gòu)造函數(shù)
         * @param insertedCount 插入的文檔數(shù)
         * @param modifiedCount 修改的文檔數(shù)
         * @param deletedCount 刪除的文檔數(shù)
         */
        public BulkOperationsResult(long insertedCount, long modifiedCount, long deletedCount) {
            this.insertedCount = insertedCount;
            this.modifiedCount = modifiedCount;
            this.deletedCount = deletedCount;
        }
    }
    
    /**
     * 批量更新操作封裝類
     * 功能:封裝單個批量更新操作的查詢條件和更新內(nèi)容
     * 
     * 包含信息:
     * - query: 查詢條件(用于匹配要更新的文檔)
     * - update: 更新操作(包含要更新的字段和新值)
     * 
     * 使用場景:
     * - 構(gòu)造批量更新操作列表
     * - 傳遞給bulkUpdate()方法
     * 
     * 示例:
     * ```java
     * Query query = new Query(Criteria.where("status").is(0));
     * Update update = new Update().set("status", 1);
     * BulkUpdateOperation operation = new BulkUpdateOperation(query, update);
     * ```
     */
    @Data
    public static class BulkUpdateOperation {
        // 查詢條件(用于匹配要更新的文檔)
        private Query query;
        // 更新操作(包含要更新的字段和新值)
        private Update update;
        
        /**
         * 構(gòu)造函數(shù)
         * @param query 查詢條件
         * @param update 更新操作
         */
        public BulkUpdateOperation(Query query, Update update) {
            this.query = query;
            this.update = update;
        }
    }
}

基礎(chǔ)CRUD操作

實(shí)體類示例

package com.example.mongodb.entity;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * 用戶實(shí)體類
 * 
 * 注解說明:
 * - @Document: 指定對應(yīng)的MongoDB集合名稱
 * - @Id: 指定主鍵字段
 * - @Indexed: 為字段創(chuàng)建索引
 * - @Field: 指定字段在MongoDB中的名稱
 */
@Data
@Document(collection = "user")
public class User implements Serializable {
    
    // 主鍵,MongoDB自動生成ObjectId
    @Id
    private String id;
    
    // 用戶名,創(chuàng)建唯一索引
    @Indexed(unique = true)
    @Field("username")
    private String username;
    
    // 密碼
    @Field("password")
    private String password;
    
    // 郵箱
    @Field("email")
    private String email;
    
    // 手機(jī)號
    @Field("phone")
    private String phone;
    
    // 年齡
    @Field("age")
    private Integer age;
    
    // 性別(0-未知,1-男,2-女)
    @Field("gender")
    private Integer gender;
    
    // 狀態(tài)(0-禁用,1-啟用)
    @Field("status")
    private Integer status;
    
    // 標(biāo)簽數(shù)組
    @Field("tags")
    private List<String> tags;
    
    // 創(chuàng)建時間
    @Field("create_time")
    private Date createTime;
    
    // 更新時間
    @Field("update_time")
    private Date updateTime;
}

Service層示例

package com.example.mongodb.service;

import com.example.mongodb.entity.User;
import com.example.mongodb.utils.MongoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 用戶服務(wù)類 - 演示如何使用MongoUtils工具類
 */
@Service
public class UserService {
    
    @Autowired
    private MongoUtils<User> mongoUtils;
    
    /**
     * 保存用戶
     * 功能:創(chuàng)建新用戶,設(shè)置創(chuàng)建時間和更新時間
     */
    public User saveUser(User user) {
        // 設(shè)置創(chuàng)建時間和更新時間
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        // 調(diào)用工具類保存
        return mongoUtils.save(user);
    }
    
    /**
     * 批量保存用戶
     * 功能:一次性保存多個用戶
     */
    public List<User> saveUsers(List<User> users) {
        // 為每個用戶設(shè)置時間
        Date now = new Date();
        users.forEach(user -> {
            user.setCreateTime(now);
            user.setUpdateTime(now);
        });
        // 批量保存
        return mongoUtils.saveBatch(users);
    }
    
    /**
     * 根據(jù)ID查詢用戶
     */
    public User getUserById(String id) {
        return mongoUtils.findById(id, User.class);
    }
    
    /**
     * 查詢所有用戶
     * 注意:如果數(shù)據(jù)量大,建議使用分頁查詢
     */
    public List<User> getAllUsers() {
        return mongoUtils.findAll(User.class);
    }
    
    /**
     * 根據(jù)用戶名查詢用戶
     * 功能:通過用戶名精確查詢
     */
    public User getUserByUsername(String username) {
        Query query = new Query(Criteria.where("username").is(username));
        return mongoUtils.findOne(query, User.class);
    }
    
    /**
     * 根據(jù)用戶名和密碼查詢用戶
     * 功能:用戶登錄驗(yàn)證
     */
    public User getUserByUsernameAndPassword(String username, String password) {
        Query query = new Query(Criteria.where("username").is(username)
            .and("password").is(password));
        return mongoUtils.findOne(query, User.class);
    }
    
    /**
     * 根據(jù)ID更新用戶
     * 功能:只更新傳入的字段,其他字段保持不變
     */
    public long updateUser(String id, User user) {
        // 創(chuàng)建更新對象
        Update update = new Update();
        
        // 只更新非空字段
        if (user.getUsername() != null) {
            update.set("username", user.getUsername());
        }
        if (user.getPassword() != null) {
            update.set("password", user.getPassword());
        }
        if (user.getEmail() != null) {
            update.set("email", user.getEmail());
        }
        if (user.getPhone() != null) {
            update.set("phone", user.getPhone());
        }
        if (user.getAge() != null) {
            update.set("age", user.getAge());
        }
        if (user.getGender() != null) {
            update.set("gender", user.getGender());
        }
        if (user.getStatus() != null) {
            update.set("status", user.getStatus());
        }
        
        // 更新時間
        update.set("update_time", new Date());
        
        // 執(zhí)行更新并返回修改的文檔數(shù)
        return mongoUtils.updateById(id, update, User.class).getModifiedCount();
    }
    
    /**
     * 根據(jù)ID刪除用戶
     */
    public long deleteUser(String id) {
        return mongoUtils.deleteById(id, User.class).getDeletedCount();
    }
    
    /**
     * 檢查用戶名是否存在
     */
    public boolean existsUsername(String username) {
        Query query = new Query(Criteria.where("username").is(username));
        return mongoUtils.exists(query, User.class);
    }
    
    /**
     * 統(tǒng)計(jì)用戶數(shù)量
     */
    public long countUsers() {
        return mongoUtils.count(new Query(), User.class);
    }
}

高級查詢功能

復(fù)雜查詢示例

package com.example.mongodb.service;

import com.example.mongodb.common.PageRequest;
import com.example.mongodb.entity.User;
import com.example.mongodb.utils.MongoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 高級查詢服務(wù)類 - 演示各種高級查詢功能
 */
@Service
public class UserAdvancedQueryService {
    
    @Autowired
    private MongoUtils<User> mongoUtils;
    
    /**
     * 模糊查詢用戶
     * 功能:根據(jù)用戶名模糊查詢,不區(qū)分大小寫
     */
    public List<User> searchUsers(String keyword) {
        Query query = new Query(mongoUtils.like("username", keyword));
        return mongoUtils.find(query, User.class);
    }
    
    /**
     * 多字段模糊查詢
     * 功能:同時在用戶名、郵箱、手機(jī)號中搜索關(guān)鍵詞
     */
    public List<User> multiFieldSearch(String keyword) {
        String[] fields = {"username", "email", "phone"};
        Query query = new Query(mongoUtils.multiFieldLike(fields, keyword));
        return mongoUtils.find(query, User.class);
    }
    
    /**
     * 年齡范圍查詢
     * 功能:查詢年齡在指定范圍內(nèi)的用戶
     */
    public List<User> getUsersByAgeRange(Integer minAge, Integer maxAge) {
        Query query = new Query(mongoUtils.between("age", minAge, maxAge));
        return mongoUtils.find(query, User.class);
    }
    
    /**
     * 狀態(tài)和年齡組合查詢
     * 功能:查詢指定狀態(tài)且年齡大于某個值的用戶
     */
    public List<User> getUsersByStatusAndAge(Integer status, Integer age) {
        Query query = new Query(
            Criteria.where("status").is(status)
            .and("age").gt(age)
        );
        return mongoUtils.find(query, User.class);
    }
    
    /**
     * IN查詢
     * 功能:查詢狀態(tài)在指定列表中的用戶
     */
    public List<User> getUsersByStatusList(List<Integer> statusList) {
        Query query = new Query(mongoUtils.in("status", statusList));
        return mongoUtils.find(query, User.class);
    }
    
    /**
     * 標(biāo)簽包含查詢
     * 功能:查詢包含指定標(biāo)簽的用戶
     */
    public List<User> getUsersByTag(String tag) {
        Query query = new Query(mongoUtils.arrayContains("tags", tag));
        return mongoUtils.find(query, User.class);
    }
    
    /**
     * 復(fù)合條件查詢
     * 功能:使用AND連接多個條件
     */
    public List<User> getUsersByComplexCondition(String keyword, Integer minAge, List<Integer> statusList) {
        Query query = new Query(
            new Criteria().andOperator(
                mongoUtils.like("username", keyword),
                mongoUtils.gte("age", minAge),
                mongoUtils.in("status", statusList)
            )
        );
        return mongoUtils.find(query, User.class);
    }
    
    /**
     * 分頁查詢
     * 功能:查詢所有用戶并分頁
     */
    public Page<User> getUsersByPage(PageRequest pageRequest) {
        Query query = new Query();
        return mongoUtils.findPage(query, pageRequest, User.class);
    }
    
    /**
     * 條件分頁查詢
     * 功能:查詢指定狀態(tài)的用戶并分頁
     */
    public Page<User> getUsersByPageWithCondition(Integer status, PageRequest pageRequest) {
        Query query = new Query(Criteria.where("status").is(status));
        return mongoUtils.findPage(query, pageRequest, User.class);
    }
}

高級更新操作示例

package com.example.mongodb.service;

import com.example.mongodb.entity.User;
import com.example.mongodb.utils.MongoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 高級更新服務(wù)類 - 演示各種高級更新功能
 */
@Service
public class UserAdvancedUpdateService {
    
    @Autowired
    private MongoUtils<User> mongoUtils;
    
    /**
     * 用戶年齡自增
     * 功能:將指定用戶的年齡加1
     */
    public long incrementAge(String userId) {
        Query query = new Query(Criteria.where("_id").is(userId));
        Update update = mongoUtils.increment("age", 1);
        return mongoUtils.updateFirst(query, update, User.class).getModifiedCount();
    }
    
    /**
     * 批量添加標(biāo)簽
     * 功能:向用戶的標(biāo)簽數(shù)組添加多個標(biāo)簽
     */
    public long addTags(String userId, List<String> newTags) {
        Query query = new Query(Criteria.where("_id").is(userId));
        for (String tag : newTags) {
            Update update = mongoUtils.push("tags", tag);
            mongoUtils.updateFirst(query, update, User.class);
        }
        return newTags.size();
    }
    
    /**
     * 批量刪除標(biāo)簽
     * 功能:從用戶的標(biāo)簽數(shù)組刪除多個標(biāo)簽
     */
    public long removeTags(String userId, List<String> tagsToRemove) {
        Query query = new Query(Criteria.where("_id").is(userId));
        for (String tag : tagsToRemove) {
            Update update = mongoUtils.pull("tags", tag);
            mongoUtils.updateFirst(query, update, User.class);
        }
        return tagsToRemove.size();
    }
    
    /**
     * 批量添加標(biāo)簽(一次性)
     * 功能:使用pushAll一次性添加多個標(biāo)簽,性能更好
     */
    public long addTagsBatch(String userId, String[] newTags) {
        Query query = new Query(Criteria.where("_id").is(userId));
        Update update = mongoUtils.pushAll("tags", newTags);
        return mongoUtils.updateFirst(query, update, User.class).getModifiedCount();
    }
    
    /**
     * 更新用戶狀態(tài)(存在則更新,不存在則設(shè)置默認(rèn)值)
     * 功能:演示setOnInsert的使用
     */
    public long updateStatusWithDefault(String userId, Integer status) {
        Query query = new Query(Criteria.where("_id").is(userId));
        Update update = mongoUtils.setOnInsert("status", 1);
        update.set("status", status);
        return mongoUtils.updateFirst(query, update, User.class).getModifiedCount();
    }
    
    /**
     * 重命名字段
     * 功能:將字段名從oldName改為newName
     */
    public long renameField(String userId, String oldName, String newName) {
        Query query = new Query(Criteria.where("_id").is(userId));
        Update update = mongoUtils.rename(oldName, newName);
        return mongoUtils.updateFirst(query, update, User.class).getModifiedCount();
    }
    
    /**
     * 刪除字段
     * 功能:從文檔中刪除指定字段
     */
    public long removeField(String userId, String fieldName) {
        Query query = new Query(Criteria.where("_id").is(userId));
        Update update = mongoUtils.unset(fieldName);
        return mongoUtils.updateFirst(query, update, User.class).getModifiedCount();
    }
    
    /**
     * 更新時間戳
     * 功能:將update_time字段更新為當(dāng)前時間
     */
    public long updateTimestamp(String userId) {
        Query query = new Query(Criteria.where("_id").is(userId));
        Update update = mongoUtils.currentDate("update_time");
        return mongoUtils.updateFirst(query, update, User.class).getModifiedCount();
    }
    
    /**
     * 批量更新操作
     * 功能:批量更新多個用戶的狀態(tài)
     */
    public long bulkUpdateUsers(List<String> userIds, Integer newStatus) {
        List<MongoUtils.BulkUpdateOperation> updates = new java.util.ArrayList<>();
        
        for (String userId : userIds) {
            Query query = new Query(Criteria.where("_id").is(userId));
            Update update = new Update().set("status", newStatus);
            updates.add(new MongoUtils.BulkUpdateOperation(query, update));
        }
        
        MongoUtils.BulkOperationsResult result = mongoUtils.bulkUpdate(updates, User.class);
        return result.getModifiedCount();
    }
}

聚合操作示例

package com.example.mongodb.service;

import com.example.mongodb.entity.User;
import com.example.mongodb.utils.MongoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 聚合查詢服務(wù)類 - 演示各種聚合操作
 */
@Service
public class UserAggregationService {
    
    @Autowired
    private MongoUtils<User> mongoUtils;
    
    /**
     * 按性別分組統(tǒng)計(jì)用戶數(shù)量
     */
    public List<Map> groupCountByGender() {
        return mongoUtils.groupCount("gender", User.class);
    }
    
    /**
     * 按狀態(tài)分組統(tǒng)計(jì)用戶數(shù)量
     */
    public List<Map> groupCountByStatus() {
        return mongoUtils.groupCount("status", User.class);
    }
    
    /**
     * 按年齡段分組統(tǒng)計(jì)
     * 功能:自定義聚合管道,按10歲一個年齡段分組
     */
    public List<Map> groupCountByAgeRange() {
        Aggregation aggregation = Aggregation.newAggregation(
            // 使用表達(dá)式將年齡分段:0-9, 10-19, 20-29...
            Aggregation.project()
                .andExpression("floor(age / 10) * 10").as("ageRange"),
            // 按年齡段分組統(tǒng)計(jì)
            Aggregation.group("ageRange")
                .count().as("count"),
            // 按年齡段升序排序
            Aggregation.sort(org.springframework.data.domain.Sort.Direction.ASC, "_id")
        );
        
        AggregationResults<Map> results = mongoUtils.aggregate(aggregation, User.class, Map.class);
        return results.getMappedResults();
    }
    
    /**
     * 統(tǒng)計(jì)各狀態(tài)用戶的平均年齡
     */
    public List<Map> groupAvgAgeByStatus() {
        return mongoUtils.groupAvg("status", "age", User.class);
    }
    
    /**
     * 查找最大年齡
     */
    public Object getMaxAge() {
        return mongoUtils.max("age", User.class);
    }
    
    /**
     * 查找最小年齡
     */
    public Object getMinAge() {
        return mongoUtils.min("age", User.class);
    }
    
    /**
     * 計(jì)算平均年齡
     */
    public Double getAvgAge() {
        return mongoUtils.avg("age", User.class);
    }
    
    /**
     * 統(tǒng)計(jì)總年齡
     */
    public Double getSumAge() {
        return mongoUtils.sum("age", User.class);
    }
    
    /**
     * 復(fù)雜聚合查詢:按狀態(tài)分組,統(tǒng)計(jì)數(shù)量、平均年齡、最大年齡
     */
    public List<Map> complexGroupByStatus() {
        Aggregation aggregation = Aggregation.newAggregation(
            // 按狀態(tài)分組
            Aggregation.group("status")
                // 統(tǒng)計(jì)用戶數(shù)
                .count().as("userCount")
                // 統(tǒng)計(jì)平均年齡
                .avg("age").as("avgAge")
                // 統(tǒng)計(jì)最大年齡
                .max("age").as("maxAge")
                // 統(tǒng)計(jì)最小年齡
                .min("age").as("minAge"),
            // 按用戶數(shù)降序排序
            Aggregation.sort(org.springframework.data.domain.Sort.Direction.DESC, "userCount")
        );
        
        AggregationResults<Map> results = mongoUtils.aggregate(aggregation, User.class, Map.class);
        return results.getMappedResults();
    }
}

最佳實(shí)踐

1. 索引優(yōu)化

為常用查詢字段創(chuàng)建索引

@Indexed
private String username;

創(chuàng)建復(fù)合索引優(yōu)化多字段查詢

@CompoundIndex(name = "idx_status_create_time", def = "{'status': 1, 'createTime': -1}")

避免過度索引

  • 索引會提高查詢性能,但會降低寫入性能
  • 建議為高頻查詢字段創(chuàng)建索引
  • 定期分析慢查詢,優(yōu)化索引

2. 查詢優(yōu)化

只查詢需要的字段

Query query = new Query();
query.fields().include("username").include("email");

避免深度分頁

  • skip()在數(shù)據(jù)量大時性能較差
  • 考慮使用基于游標(biāo)的分頁

使用索引覆蓋查詢

// 查詢條件和排序都使用索引字段
query.addCriteria(Criteria.where("status").is(1));
query.with(Sort.by(Sort.Direction.DESC, "createTime"));

3. 批量操作

大量數(shù)據(jù)插入使用批量插入

mongoUtils.saveBatch(users);

多文檔更新使用BulkOperations

mongoUtils.bulkUpdate(updates, User.class);

總結(jié)

本文詳細(xì)介紹了SpringBoot整合MongoDB的完整工具類實(shí)現(xiàn),涵蓋了基礎(chǔ)CRUD、高級查詢、聚合操作、事務(wù)處理等功能。通過合理封裝MongoDB操作,可以顯著提高開發(fā)效率和代碼質(zhì)量。

以上就是SpringBoot整合MongoDB的完整操作指南的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot整合MongoDB的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring如何在一個事務(wù)中開啟另一個事務(wù)

    Spring如何在一個事務(wù)中開啟另一個事務(wù)

    這篇文章主要介紹了Spring如何在一個事務(wù)中開啟另一個事務(wù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • Java鎖升級的實(shí)現(xiàn)過程

    Java鎖升級的實(shí)現(xiàn)過程

    這篇文章主要介紹了Java鎖升級的實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Java獲取中文拼音、中文首字母縮寫和中文首字母的示例

    Java獲取中文拼音、中文首字母縮寫和中文首字母的示例

    本文主要介紹了Java獲取中文拼音、中文首字母縮寫和中文首字母,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2016-10-10
  • java使用HttpSession實(shí)現(xiàn)QQ訪問記錄

    java使用HttpSession實(shí)現(xiàn)QQ訪問記錄

    這篇文章主要介紹了java使用HttpSession實(shí)現(xiàn)QQ的訪問記錄的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • Spring配置文件和mybatis詳解

    Spring配置文件和mybatis詳解

    MyBatis是一款優(yōu)秀的持久層框架,支持自定義SQL、存儲過程、高級映射以及多種配置方式,本文給大家介紹Spring配置文件和mybatis的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧
    2025-10-10
  • Java開發(fā)第一個RESTful接口完全攻略

    Java開發(fā)第一個RESTful接口完全攻略

    restful接口是一種基于http協(xié)議的網(wǎng)絡(luò)應(yīng)用程序接口設(shè)計(jì)風(fēng)格,它強(qiáng)調(diào)資源的表現(xiàn)形式和狀態(tài)轉(zhuǎn)移,下面這篇文章主要介紹了Java開發(fā)RESTful接口的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-01-01
  • jmeter正則表達(dá)式的使用

    jmeter正則表達(dá)式的使用

    在jmeter中,可以利用正則表達(dá)式提取器來幫助我們完成這一動作,本文就詳細(xì)的介紹一下應(yīng)該如何使用,感興趣的可以了解一下
    2021-11-11
  • SpringCloud中的Eureka集群配置方法

    SpringCloud中的Eureka集群配置方法

    這篇文章主要介紹了SpringCloud中的Eureka集群配置,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • 阿里開源Java診斷工具神器使用及場景詳解

    阿里開源Java診斷工具神器使用及場景詳解

    這篇文章主要為大家介紹了阿里開源Java診斷工具神器使用及場景詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Spring?Security?Oauth2整合JWT的詳細(xì)步驟和核心配置

    Spring?Security?Oauth2整合JWT的詳細(xì)步驟和核心配置

    這篇文章主要介紹了Spring?Security?Oauth2整合JWT的詳細(xì)步驟和核心配置,包括依賴引入、JWT工具類、OAuth2和資源服務(wù)器配置以及SpringSecurity配置,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-11-11

最新評論

辽宁省| 五华县| 汝南县| 井冈山市| 沾化县| 曲水县| 松江区| 博客| 诸城市| 江油市| 始兴县| 炉霍县| 大余县| 繁峙县| 兴业县| 确山县| 商都县| 昭觉县| 武安市| 台州市| 西华县| 乌兰县| 龙陵县| 邓州市| 灵石县| 天门市| 色达县| 长宁县| 阳信县| 南漳县| 彭州市| 罗源县| 井冈山市| 赤城县| 青岛市| 鲜城| 威海市| 托里县| 高碑店市| 专栏| 循化|