IV.Indexes(索引)

本文详细介绍了如何在MongoDB中创建、管理和优化索引,包括单字段索引、复合索引、文本索引、哈希索引以及2dsphere索引的使用。还涵盖了TTL索引、唯一索引、部分索引和稀疏索引等特性,以及索引在查询、排序和性能优化中的应用策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Recipe 4-1. Working with Indexes(使用索引)
    准备数据
        db.employee.insert({empId:1,empName:"John",state:"KA",country:"India"})
        db.employee.insert({empId:2,empName:"Smith",state:"CA",country:"US"})
        db.employee.insert({empId:3,empName:"James",state:"FL",country:"US"})
        db.employee.insert({empId:4,empName:"Josh",state:"TN",country:"India"})
        db.employee.insert({empId:5,empName:"Joshi",state:"HYD",country:"India"})
    1.创建索引
        db.employee.createIndex({empId:1})
    2.创建多个域的索引
        db.employee.createIndex({empId:1,empName:1})
    3.查看索引
        db.employee.getIndexes()
    4.删除指定索引
        db.employee.dropIndex({empId:1,empName:1})
    5.删除所有索引
        db.employee.dropIndexes()
    6.注意_id是默认索引,是不能删除
Recipe 4-2. Index Types(索引类型)
    准备数据
        db.employeeproject.insert({empId:1001,empName:"John",projects:["Hadoop","MongoDB"]})
        db.employeeproject.insert({empId:1002,empName:"James",projects:["MongoDB","Spark"]})
    1.多个key的索引--即指定数据中的某个作为索引
         db.employeeproject.createIndex({projects:1})
    2.文本索引
        有这样的数据
            db.post.insert({
                "post_text": "Happy Learning",
                "tags": [
                "mongodb",
                "10gen"
                ]
            })
        创建索引:db.post.createIndex({post_text:"text"})
        查询:db.post.find({$text:{$search:"Happy"}})
    3.Hashed索引
        有这样的数据
            db.user.insert({userId:1,userName:"John"})
            db.user.insert({userId:2,userName:"James"})
            db.user.insert({userId:3,userName:"Jack"})
        创建Hashed索引:db.user.createIndex( { userId: "hashed" } )
    4.2dsphere索引
        有这样的数据
            db.schools.insert( {name: "St.John's School",location: { type: "Point", coordinates: [ -73.97, 40.77 ] },} );
            db.schools.insert( {name: "St.Joseph's School",location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] },} );
            db.schools.insert( {name: "St.Thomas School",location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] },} );
        创建索引:db.schools.createIndex( { location : "2dsphere" } )
        查询(位置):
            db.schools.find({location:{$near:{$geometry: { type:"Point", coordinates: [ -73.9667, 40.78 ] },$minDistance:500,$maxDistance: 1500}}})

Recipe 4-3. Index Properties(索引属性)
    
    1.TTL索引
      准备数据
        db.credit.insert({credit:16})
        db.credit.insert({credit:18})
        db.credit.insert({credit:12})
        创建索引:db.credit.createIndex( { credit: 1 }, { expireAfterSeconds: 35 } );
    2.Unique索引
        准备数据
            db.student.insert({_id:1,studid:101,studname:"John"})
            db.student.insert({_id:2,studid:102,studname:"Jack"})
            db.student.insert({_id:3,studid:103,studname:"James"})
        创建索引:db.student.createIndex({"studid":1}, {unique:true})
        插入数据会报错:db.student.insert([{_id:1,studid:101,studname:"John"}])
    3.Partial索引
        可以使用的操作符:$exists,$gt,$gte,$lt,$lte,$type,$and
        准备数据
            db.person.insert({personName:"John",age:16})
            db.person.insert({personName:"James",age:15})
            db.person.insert({personName:"John",hobbies:["sports","music"]})
        创建索引
            db.person.createIndex( { age: 1},{partialFilterExpression: {age: { $gt: 15 }}})
        查询:db.person.find( { age: { $gt: 15 } } )
    4.Sparse索引
        准备数据
            db.person.insert({personName:"John",age:16})
            db.person.insert({personName:"James",age:15})
            db.person.insert({personName:"John",hobbies:["sports","music"]})
        创建索引
            db.person.createIndex( { age: 1 }, { sparse: true } );
        查询:db.person.find().hint( { age: 1 } ).count();
                db.person.find().count();
Recipe 4-4. Indexing Strategies(索引策略)
    1.创建索引用于查询
        db.employee.createIndex({empId:1})
        db.employee.createIndex({empId:1,empName:1})
    2.使用索引来排序结果
        db.employee.createIndex({empId:1})
        db.employee.find().sort({empId:1})
    3.排序多个域
        db.employee.createIndex({empId:1,empName:1})
        db.employee.find().sort({empId:1,empName:1})
    4.查询索引可以使用的大小
        db.employee.totalIndexSize()

<think>我们正在处理一个关于Java Persistence API(JPA)的错误:`java.lang.NoSuchMethodError:javax.persistence.Table.indexes()`。这个错误通常发生在运行时,表示JPA的某个版本中不存在`Table.indexes()`方法。根据提供的引用,我们可以分析原因并给出解决方案。###错误原因分析1.**JPA API版本不一致**:`indexes()`方法是在JPA2.1版本中引入的。如果项目依赖的JPA版本低于2.1(例如JPA2.0),则`Table`类中不存在`indexes()`方法,从而导致此错误[^1][^2]。 2. **类路径冲突**:项目中可能存在多个不同版本的JPA APIjar包,导致类加载器加载了错误版本的`Table`类[^3]。 3. **应用服务器提供的JPA版本过低**:例如,WebLogic等应用服务器可能自带了较低版本的JPAAPI,与项目所需的JPA2.1+版本冲突[^2]。###解决方案####1.确保使用JPA2.1或更高版本在Maven项目中,添加正确的依赖:```xml<dependency><groupId>javax.persistence</groupId><artifactId>javax.persistence-api</artifactId><version>2.2</version> <!--或更高版本--><scope>provided</scope> <!--如果应用服务器已提供,则使用provided--> </dependency>``` 或者使用Hibernate提供的JPA2.1API:```xml<dependency><groupId>org.hibernate.javax.persistence</groupId><artifactId>hibernate-jpa-2.1-api</artifactId><version>1.0.0.Final</version></dependency> ```####2.排除冲突的依赖检查项目中是否引入了低版本的JPA API,并通过Maven排除:```xml<dependency><groupId>some.group</groupId><artifactId>some-artifact</artifactId><version>X.X</version><exclusions><exclusion><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId></exclusion></exclusions></dependency> ```####3.解决应用服务器与项目的JPA版本冲突-**对于WebLogic/Tomcat等服务器**:确保服务器提供的JPA版本与项目一致。如果服务器版本较低,可以配置服务器使用项目的JPA库(例如,将JPA2.1+的jar包放在`WEB-INF/lib`下)[^2][^4]。 -**或者**:在应用服务器中禁用自带的JPA,强制使用项目中的JPA库。具体方法因服务器而异。####4.检查MongoDB驱动等第三方库的兼容性某些第三方库(如MongoDB驱动)可能引入了旧版JPAAPI,导致冲突。排除这些库中的旧版JPA依赖[^5]: ```xml<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-mongodb</artifactId><version>1.7.0.RELEASE</version><exclusions><exclusion><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId></exclusion></exclusions></dependency> ```###验证步骤1.使用`mvndependency:tree`命令检查依赖树,确认没有低版本的JPA API。 2.在运行时检查类路径,确保加载的是正确版本的`Table.class`(如引用[^3]所示)。###总结该错误主要由JPA版本不匹配或类路径冲突引起。通过统一项目中的JPA版本为2.1+,并排除冲突的依赖,可以解决此问题。在应用服务器部署时,注意服务器提供的JPA版本,必要时覆盖服务器默认库。§§相关问题§§1.如何查看Maven项目的依赖树? 2.在WebLogic中如何覆盖自带的JPA库? 3. JPA2.1引入了哪些新特性?4.如何解决Java应用中的`NoSuchMethodError`?</think>### 解决 `java.lang.NoSuchMethodError: javax.persistence.Table.indexes()` 错误 该错误表示 JPA API 版本冲突,`indexes()` 方法是 JPA 2.1 新增的 API,当运行时加载了旧版 JPA 库(如 JPA 2.0)时会出现此问题。以下是解决方案: #### 1. **统一 JPA 版本 (核心方案)** - **添加 JPA 2.1+ 依赖** 在 Maven 中明确引入 JPA 2.1+ API: ```xml <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> <!-- 或更高 --> </dependency> ``` - **或使用 JavaEE API** 如果项目基于 JavaEE 6+: ```xml <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>8.0</version> <!-- 需与服务器版本匹配 --> <scope>provided</scope> </dependency> ``` #### 2. **排除冲突依赖** 检查依赖树,排除旧版 JPA: ```bash mvn dependency:tree | grep "persistence" ``` 在冲突的依赖中排除旧版本: ```xml <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <exclusions> <exclusion> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> </exclusion> </exclusions> </dependency> ``` #### 3. **服务器部署配置** - **Tomcat** 将 JPA 2.1+ 的 JAR(如 `javax.persistence-api-2.2.jar`)放入 `WEB-INF/lib`。 - **WebLogic** 在 `weblogic.xml` 中优先加载项目库: ```xml <container-descriptor> <prefer-application-packages> <package-name>javax.persistence.*</package-name> </prefer-application-packages> </container-descriptor> ``` #### 4. **第三方库冲突处理** 如 MongoDB 驱动引入旧 JPA,需排除: ```xml <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <exclusions> <exclusion> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> </exclusion> </exclusions> </dependency> ``` #### 验证是否解决 检查运行时加载的 `Table.class`: ```java System.out.println(Table.class.getProtectionDomain().getCodeSource().getLocation()); ``` 应输出 JPA 2.1+ 的 JAR 路径,而非旧版本[^3]。 > **根本原因**:项目编译时使用 JPA 2.1+ API,但运行时加载了旧版 JPA 库(如 JPA 2.0)。统一版本即可解决[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值