Spring Data MongoDB复合索引失效?@CompoundIndexes正确使用与排查指南
先说我碰到的一个真实场景。某个后端服务的订单列表页筛选条件是“用户ID 状态 下单时间范围”数据量到千万级之后接口稳定在 3 秒以上。代码里明明写了CompoundIndexes注解DBA 却说 MongoDB 里看不到对应索引explain出来全是 COLLSCAN。后来查了半天问题出在一个特别隐蔽的地方实体类用了Field自定义存储字段名而CompoundIndex的def里写的却是 Java 属性名索引建在了不存在的字段上。这篇文章就是来把CompoundIndexes这件事讲透的它到底该怎么写、为什么你写了却没效果、以及怎么一步步验证它是真没建还是建了没用。适合正在调 MongoDB 查询性能的开发者也适合刚接触 Spring Data MongoDB 的新手对照复用。1. 复合索引的定位先弄清它解决什么问题1.1 单字段索引不够用的时候查询慢第一反应是加索引这个思路没错但单字段索引有它的边界。假设orders集合上有一个userId_1单字段索引你执行find({userId: u100, status: PAID, createdAt: {$gte: ...}})MongoDB 确实能用userId索引快速定位到 u100 的所有订单假如有一万条然后它要把这一万条文档逐条加载出来在内存里过滤status和createdAt。要是 u100 是个高频用户这个数量可能变成十万、几十万。此时你会发现索引是有的查询还是慢。有人会说那给status也加个单字段索引不就行了MongoDB 确实支持索引交叉Index Intersection多个单字段索引在少数等值条件下可以协作但这跟真正的复合索引完全是两码事。索引交叉能覆盖的场景很有限而且解决不了排序走索引的问题执行计划也可能不稳定。面向“多字段过滤 排序”的查询正确工具就是复合索引。这里必须说清楚一个常见误解在字段 A 上写Indexed在字段 B 上再写一个Indexed得到的是两个独立的单字段索引不是复合索引。这种写法下查询优化器只能挑其中一个索引去扫描另一个字段的回表过滤照样发生。想想电话簿的类比一本按“姓氏”排的电话簿和一本按“名字”排的电话簿并没有解决“按姓氏加名字查人”的效率问题真正有用的是同一本里先按姓氏再按名字排。1.2 复合索引的工作方式与匹配规则复合索引的本质是把多个字段拼在一起形成一棵排序树。打个比方一本电话簿先按姓氏排姓氏相同的再按名字排。你查“张三”可以直接翻到查“张X”也能用前缀方式翻但你说“我要找所有名字叫三的人”这本电话簿就帮不上忙了。对应到 MongoDB 就是最左前缀原则。索引{a: 1, b: 1, c: 1}能支撑的查询模式包括只过滤a过滤a b过滤a b c或者等值a b加范围c但它支撑不了只过滤b、只过滤c、或过滤b c的查询。很多“索引没效果”的真相就在这里索引其实建出来了但你的查询条件压根不在索引前缀覆盖范围内。比如索引是{userId: 1, status: 1, createdAt: -1}而你天天跑的是find({status: PAID, createdAt: {$gte: ...}})优化器没法用这个索引于是老老实实 COLLSCAN。范围条件还有一层讲究{a: 1, b: 1, c: 1}在面对a等值、b范围、c等值的查询时c的等值条件通常很难再压缩索引扫描范围。所以设计复合索引时经验做法是把等值字段放前面范围字段放后面排序字段放在两者之间这也就是后面要说的 ESR 原则。1.3 什么时候才需要给字段建复合索引复合索引不是越多越好。每多一个索引写入时就要多维护一棵 B 树存储和写入开销是实打实的。我判断要不要建复合索引一般看三条查询是否高频且同时包含多个过滤字段现有单字段索引是否已造成大量回表和内存过滤查询是否带有排序需求如果某个组合查询一周出现不了几次慢几秒也完全能接受如果它是首页接口的核心查询那就值得为它专门设计索引。另外要注意选择性很差的字段比如status只有三五个值不太适合单独放在最左边更适合跟在其它高选择性等值字段后面。复合索引的典型收益场景场景查询特征单字段索引为什么不行用户维度聚合userId status createTime单字段索引筛选后回表量太大后台管理列表状态 时间范围 分页排序过滤和排序都消化在索引里才快防重复业务记录多个业务字段组合唯一只有 unique 复合索引能保证组合唯一2. CompoundIndex 与 CompoundIndexes 的标准用法2.1 注解放哪、怎么写才是对的Spring Data MongoDB 里CompoundIndex和它的容器CompoundIndexes都是类级别注解目标类型是TYPE。意思就是必须写在实体类上不能写在字段上。有人习惯性地把它当Indexed用往属性上一放直接编译不过。如果只有一个复合索引直接用CompoundIndex就够了不一定要套CompoundIndexesDocument(collection orders) CompoundIndex(name idx_uid_status_time, def {userId: 1, status: 1, createdAt: -1}) public class Order { Id private String id; private String userId; private String status; private Date createdAt; }CompoundIndexes是容器注解当你想在同一个集合上声明两个及以上复合索引时用它把多个CompoundIndex包起来。只建一个索引却套一层容器没有意义但也不会报错。2.2 常用参数逐个说清楚CompoundIndex常用的属性是这几个def必填JSON 字符串形式的索引键定义。1表示升序-1表示降序。例如{userId: 1, createdAt: -1}。name索引名称。不写的话MongoDB 会按键自动生成类似userId_1_createdAt_-1的名字。建议显式命名后面会讲原因。unique是否唯一索引。为true时整个键组合的值不能重复。sparse稀疏索引只对含这些字段的文档建索引。配合唯一约束时很有用。background历史遗留参数。MongoDB 4.2 之前用来建后台索引4.2 之后索引默认都是混合构建这个参数基本没用了新版里还标了废弃。expireAfterSecondsTTL 参数。注意TTL 只支持单字段索引复合索引设置它没有实际意义。partialFilter部分索引过滤条件只对满足条件的文档建索引。collation排序规则用于大小写不敏感等场景。options附加索引选项JSON 字符串形式传入。举两个例子CompoundIndex( name idx_uid_status_unique, def {userId: 1, status: 1}, unique true )CompoundIndex( name idx_status_time_partial, def {status: 1, createdAt: -1}, partialFilter {status: {$exists: true}} )partialFilter只对status字段存在的文档建索引适合某些业务中大部分文档压根没有这个字段的场景既能减少索引体积又能避免稀疏模式下的一些坑。2.3 多个复合索引用容器注解包起来一个实体类对应一个集合集合上可以有多个复合索引。用CompoundIndexes包起来Document(collection orders) CompoundIndexes({ CompoundIndex(name idx_uid_status, def {userId: 1, status: 1}), CompoundIndex(name idx_status_time, def {status: 1, createdAt: -1}) }) public class Order { // 字段省略 }注意CompoundIndexes本身没有def、name这些属性它的唯一作用就是把多个CompoundIndex组织在一起。我见过有人试图在CompoundIndexes上直接写def那是编译不过的语义上也不是这么用的。2.4 一个可以直接抄走的完整示例我把一个实际项目里用过的简化版本放这里包含索引声明、字段映射、仓库查询三块Document(collection orders) CompoundIndexes({ CompoundIndex(name idx_uid_status_created, def {userId: 1, status: 1, createdAt: -1}), CompoundIndex(name idx_phone_created, def {phone: 1, createdAt: -1}, sparse true) }) public class Order { Id private String id; private String userId; private String phone; private String status; private Date createdAt; // getter / setter 省略 }对应仓库接口public interface OrderRepository extends MongoRepositoryOrder, String { ListOrder findByUserIdAndStatusAndCreatedAtBetween( String userId, String status, Date start, Date end); ListOrder findByPhoneAndCreatedAtGreaterThan(String phone, Date start); }findByUserIdAndStatusAndCreatedAtBetween会命中idx_uid_status_created的最左前缀等值userId 等值status 范围createdAt。findByPhoneAndCreatedAtGreaterThan命中第二个索引。两套查询都能走 IXSCAN而不是回表再过滤。3. CompoundIndexes 没效果的七大成因3.1 字段名映射对不上这是最常见也最隐蔽的一个原因。实体类里经常用Field自定义存储字段名比如Document(collection users) public class User { Field(nick_name) private String nickname; Field(reg_time) private Date regTime; }如果你的CompoundIndex写成了下面这样CompoundIndex(def {nickname: 1, regTime: -1})那就有风险了。Spring Data MongoDB 在多数版本里是直接把def字符串里的键名当作 MongoDB 字段名传给服务端的nickname和regTime这两个字段在文档里根本不存在真实字段是nick_name和reg_time。结果就是索引确实创建成功了但建在了一堆不存在的字段上你的查询照样走 COLLSCAN。这个行为在不同版本之间可能有一点点差异个别版本会尝试对def做属性名到字段名的转换但千万别赌这个行为。最稳的做法是def里直接写 MongoDB 文档里的真实字段名建完立刻到 shell 里用getIndexes()确认。对比之下写在字段上的Indexed会自动解析Field映射后的名字所以单字段索引一般没这个问题CompoundIndex的def是原始字符串才容易踩坑。3.2 自动建索引被关掉了Spring Data 默认会在应用上下文启动阶段扫描实体类注解并自动创建索引但这条链路可以被关掉。检查你的配置文件或环境变量里有没有出现spring.data.mongodb.auto-index-creationfalse一旦为false所有Indexed、CompoundIndex、TextIndex都不会自动创建。有些人从老项目拷贝配置自己都不知道有这个开关。尤其注意如果团队里约定“索引全部由 DBA 或迁移脚本管理”有人在配置里把这个开关关了那你的注解当然“没效果”。在非 Spring Boot 的纯 Spring Data 项目里则需要手动给MongoMappingContext开启autoIndexCreation或者把索引创建纳入初始化流程否则同样不会自动建。针对这种场景我的经验是第一优先去项目里全局搜auto-index-creation和autoIndexCreation两个词都可能出现。3.3 注解放错地方、集合没被扫描到复合索引注解只能放在类上。除了编译期错误还有一种“能编译、没效果”的情况实体类没有加Document或者类所在的包不在 Spring Data MongoDB 的实体扫描范围内。索引解析器认的是纳入映射上下文的PersistentEntity如果你的类不是一个被管理的实体注解再规范也没人处理。排查方法很简单给这个类写一个MongoRepository或者用MongoTemplate插入一条数据。如果集合里能看到字段说明映射正常如果连集合都建不出来大概率就是实体没被识别。还有一种是实体类上有Document但仓库接口没有继承MongoRepository也不影响索引创建只要实体能被扫描到就行。3.4 索引已存在但键或选项不一致MongoDB 里同一个集合的索引名必须唯一而且同名索引不允许用不同的键定义再次创建。这句话对应两种常见的部署事故改动了def但保留了原来的name重启时直接报Index with name: xxx already exists with different options。不指定name默认名由键生成。改了字段或方向后默认名也跟着变新索引名和老索引名不同但键相同MongoDB 会提示重复键索引或者直接忽略你的新定义。这种“索引建不进去”的情况经常被误判成注解没生效。解决办法不是改注解重跑而是先dropIndex掉老索引再重启。在生产环境这属于需要走变更流程的操作别在没人审批的情况下直接执行。3.5 unique 约束与存量数据冲突unique true的复合索引在建索引时MongoDB 会对集合里所有现有文档做唯一性校验。只要存量数据里存在两组文档它们的键组合值相同索引创建就会以 E11000 duplicate key 错误失败。还有一个更隐蔽的空值问题。复合索引{a: 1, b: 1}设为唯一如果有一百条文档都缺a和b默认情况下它们索引键都是null彼此之间就“撞车”了。这种情况通常要配合sparse true让缺失字段的文档不进索引才能绕过唯一约束的误伤。上线前可以先跑一段聚合查一下目标键组合的重复情况再做决定db.orders.aggregate([ { $group: { _id: { userId: $userId, status: $status }, count: { $sum: 1 } } }, { $match: { count: { $gt: 1 } } }, { $limit: 20 } ])3.6 集合张冠李戴还有一种经典乌龙CompoundIndexes写在类 A 上这个类映射到集合 A但你的业务查询用的是类 B映射到集合 B或者干脆是mongoTemplate直接指定了别的集合名。索引建在了 A 的集合里你盯着 B 的集合查当然看不到。多个实体映射到同一个集合也很容易互相踩。两个类都往orders集合映射一个声明了idx_uid另一个也声明同名索引但def不一样启动时就会打架后处理的直接失败。这种场景建议收敛建模一个逻辑集合尽量只对应一个主实体类其它情况用 DTO 或投影处理。3.7 依赖、版本与自定义配置问题如果项目里用的是自定义MongoTemplate、自建MongoClient工厂或者排掉了 Spring Boot 的 MongoAutoConfiguration自动建索引的监听器可能压根没注册。这种情况在老项目里偶尔遇到有人为了做多数据源手写了一套配置结果把索引自动创建链路弄丢了。版本方面Spring Boot 2.x 和 3.x、Spring Data MongoDB 3/4 之间的整体机制一致但个别属性、包名有变化。索引注解一直在org.springframework.data.mongodb.core.index下位置稳定spring.data.mongodb.auto-index-creation这个属性在多个 Boot 版本之间也保持稳定。真正要注意的是升级大版本后回归验证一遍索引创建别只盯着功能跑通就上线。4. 排查与验证怎么确认索引真的“没效果”4.1 第一时间看启动日志Spring Data 自动创建索引时会有日志输出。找不到的话先把日志级别调低logging.level.org.springframework.data.mongodbDEBUG启动后搜索Creating index或Index关键字正常能看到类似下面的一行Creating index on collection orders with keys: {userId: 1, status: 1, createdAt: -1}如果日志里压根没有这一行说明索引没有进入创建流程去查前面说的 3.2、3.3、3.7。如果日志里报了异常比如 duplicate key 或 index already exists去查 3.4、3.5。日志是区分“没执行”和“执行了但失败”最快的分界点。注意不同版本日志格式不完全一样但关键词大致是这个方向。4.2 用 Mongo Shell 或 Compass 看真实索引日志能证明框架执行了但索引到底建在哪、键对不对必须以 MongoDB 服务端为准。在 shell 里执行db.orders.getIndexes()输出里每一项是一个索引。重点看key字段{ userId: 1, status: 1, createdAt: -1 }。再对照实体类里Field的真实存储字段名确认没有建到错误字段上。如果数据库带命名空间前缀写成db.getSiblingDB(你的库名).orders.getIndexes()也行。4.3 explain 确认查询是否真的走了索引索引存在不代表查询会用它。最直接的方式是拿真实查询语句跑explaindb.orders.find( { userId: u100, status: PAID, createdAt: { $gte: ISODate(2024-01-01) } } ).sort({ createdAt: -1 }).explain(executionStats)看返回里的两点winningPlan.stage是否是IXSCANwinningPlan.inputStage.indexName是不是你建的那个名字executionStats.totalDocsExamined是否远小于totalKeysExamined如果stage是COLLSCAN或者虽然走了索引但不是预期的那个就要回到查询条件、字段顺序和索引前缀匹配上找原因。特别提醒下面这些情况都可能让优化器放弃你的复合索引查询条件不以索引的第一个字段开头第一个字段用了$in、$or、正则表达式或$where查询带 collation但索引没有对应 collation查询里对索引字段用了$exists: false之类的否定条件4.4 用测试代码做自动化验证启动日志和 shell 适合手查更可靠的是把索引存在性写进测试。用MongoTemplate的indexOps拿到索引信息IndexOperations indexOps mongoTemplate.indexOps(orders); for (IndexInfo info : indexOps.getIndexInfo()) { System.out.println(index: info.getName() fields: info.getIndexFields()); }在集成测试里加断言boolean found indexOps.getIndexInfo().stream() .anyMatch(info - idx_uid_status_created.equals(info.getName())); assertTrue(found);这样每次改动实体类或索引定义后跑一遍测试索引有没有创建、名字对不对立刻就知道。测试环境用DataMongoTest配合内嵌 MongoDB 或真实实例都行关键是把这个检查养成习惯。5. 几个实战经验与索引设计建议5.1 索引命名要可维护我见过太多idx_1、idx_new这种索引名出了事根本对不上号。我的习惯是idx_前缀 集合名或用途缩写 字段名缩写 方向比如idx_orders_uid_status_created_desc。名字长一点没关系getIndexes()一拉出来就知道谁是谁。更重要的是索引名字一旦确定def不能再改。真要改记住“先 drop 旧的再改注解重启”顺序不能反。否则就会出现 3.4 说的同名不同键冲突。生产环境改索引我一般写成脚本db.orders.dropIndex(idx_orders_uid_status_created_desc);然后在变更窗口重启应用或手动执行新索引的创建。不要在生产库上对着运行中的服务反复重启试错。5.2 从真实查询模式倒推索引结构设计复合索引不能拍脑袋应该从慢查询日志和业务查询代码出发。MongoDB 打开性能剖析db.setProfilingLevel(1, { slowms: 200 })执行一段时间后查system.profile集合db.system.profile.find().sort({ ts: -1 }).limit(20)看哪些查询高频、哪些docsExamined巨大按查询模式归类后再决定索引组合。经验法则是 ESR等值Equality字段放最前其次排序Sort字段最后范围Range字段。等值字段能最大化索引前缀的复用排序字段放中间让 MongoDB 可以直接从索引返回有序结果范围字段放最后因为范围条件之后的字段对压缩扫描范围帮助有限。5.3 排序方向的正确姿势排序方向和索引方向不匹配索引照样“白建”。比如高频排序是createdAt desc索引里对应字段就得是-1而不是1。混合排序更麻烦sort({status: 1, createdAt: -1})需要索引{status: 1, createdAt: -1}如果你只有{status: 1, createdAt: 1}MongoDB 虽然可能用索引做等值过滤但排序得在内存里做executionStats里会出现 SORT 阶段结果集一大照样卡。判断排序能不能走索引看一条就够了排序字段是否都包含在已用索引的键里并且顺序相同、方向全同或全反。全反的情况下 MongoDB 可以倒序读索引也算匹配。查询里同时有过滤和排序时要确保排序字段紧跟在等值字段之后且没有被范围字段隔断。5.4 生产环境建索引的几个提醒大集合建索引是个体力活。MongoDB 4.2 之后默认的混合索引构建不需要手工指定 background但构建期间仍有资源占用。千万级以上的集合尽量安排在业务低峰期操作并留足时间窗口。另外如果集合里冗余、脏数据多先清理再做唯一索引否则建索引直接失败业务上还会被打上一个“索引没生效”的标签。还有一点经常被忽略CompoundIndex的expireAfterSeconds只对单字段 TTL 有效复合索引设置它没有意义。需要做数据过期清理的单独开一个Indexed(expireAfterSeconds ...)字段索引就好。最后说一个我自己的习惯。每次新增或修改索引注解我不会只靠肉眼确认一定会做两件事启动时在日志里搜一次Creating index然后到 shell 里对一次getIndexes()。就这两个动作已经帮我在上线前挡住过好几次“索引建错字段”和“同名索引冲突”的问题。如果你也被CompoundIndexes坑过照着这篇的顺序排查一遍大概率能在字段名映射、自动建索引开关、或者存量索引冲突这三处找到那个让你毫不知情的元凶。

相关新闻

单因素方差分析全解读:从变异分解到MATLAB实现

单因素方差分析全解读:从变异分解到MATLAB实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 10:02:53 阅读更多 →
Android Camera HAL3架构拆解:从请求-响应模型到Pipeline实现

Android Camera HAL3架构拆解:从请求-响应模型到Pipeline实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 10:02:53 阅读更多 →
NMAP扫描与TCPDUMP抓包:网络可见性实战指南

NMAP扫描与TCPDUMP抓包:网络可见性实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 10:02:53 阅读更多 →

最新新闻

纯Go代码生成彩色SVG图形:零依赖实现数据可视化

纯Go代码生成彩色SVG图形:零依赖实现数据可视化

1. 为什么用 Go 来画 SVG 而不是直接截图很多人第一次听到“用 Go 画 SVG”都会愣一下:画图不是前端的事吗,或者干脆用 Python 的 matplotlib 出图不香吗?我一开始也是这么想的,直到手上一个后端服务需要每天定时生成一批带数据的…

2026/10/17 10:39:06 阅读更多 →
Jev哑巴模型:TypeSafe AI如何解决代码生成类型错误痛点

Jev哑巴模型:TypeSafe AI如何解决代码生成类型错误痛点

1. 一个不说话的模型,凭什么让开发者集体上头 第一次看到"哑巴模型"这个说法,我以为是哪个团队做了个只会输出代码、不会闲聊的极端精简模型。真正上手之后才发现,这个描述其实抓住了 Jev 最核心的产品哲学:它不靠对话能…

2026/10/17 10:39:06 阅读更多 →
CCSDS指令注入防御:轻量级签名与状态绑定机制

CCSDS指令注入防御:轻量级签名与状态绑定机制

简介:本资源是一份聚焦太空网络安全前沿议题的深度技术文档,面向CTF安全竞赛选手、航天系统安全研究人员及网络安全工程师,专门针对CCSDS协议中高危的指令注入攻击,系统性提出覆盖协议栈感知、指令语义分析、分层防御架构、端到端…

2026/10/17 10:39:06 阅读更多 →
BioBERT领域预训练模型:架构、训练策略与下游任务适配

BioBERT领域预训练模型:架构、训练策略与下游任务适配

1. 生物医学文本挖掘为什么需要专属语言模型生物医学文献的体量在过去二十年里经历了爆炸式增长,光是公开的文献数据库每年新增条目就以百万计。做生物医学文本挖掘的人都有一个共同感受:拿通用领域的语言模型直接往上套,效果往往差强人意。原…

2026/10/17 10:39:06 阅读更多 →
Control Flow Flattening与字符串动态解密实战解析

Control Flow Flattening与字符串动态解密实战解析

1. 项目概述:从一道CTF逆向题切入真实软件保护逻辑“re学习笔记(25)BUUCTF-re-[2019红帽杯]easyRE”——这个标题看似只是某位学习者在刷题平台记录的一次练习,但背后藏着逆向工程领域最典型、也最容易被初学者低估的实战切口。我…

2026/10/17 10:39:06 阅读更多 →
27. 数据产品-数据治理-4. DAMA 车轮图拆解

27. 数据产品-数据治理-4. DAMA 车轮图拆解

文章目录 前言 第一节:什么是 DAMA 车轮图?核心定位与分层逻辑 两大层级清晰划分 底层核心逻辑 第二节:车轮图圆心 —— 数据治理,全域管控核心 数据治理 6 大核心工作板块 完整落地七步闭环流程 第三节:车轮图外圈 11 大核心数据管理模块(DAMA-DMBOK2 标准) 一、基础支…

2026/10/17 10:38:06 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →