1.查询索引
List<IndexInfo> indexInfo = mongoTemplate.indexOps(Student.class).getIndexInfo();
2.删除索引
mongoTemplate.indexOps(Student.class).dropIndex("age_1");mongoTemplate.indexOps(Student.class).dropAllIndexes();
3.创建索引
单列索引、复合索引、多键值索引
全文索引,hash索引,地理位置索引(2d或2dSphere)目前只支持注解,但是不知道为什么我测试没有生效。个人还是更习惯直接命令行创建索引
@Testvoid testCreateIndex() {//1.创建单列索引Index index = new Index().on("age", Sort.Direction.ASC);String indexName = mongoTemplate.indexOps(Student.class).ensureIndex(index);Console.log(indexName);//2.创建复合索引Index compoundIndex = new Index().on("name", Sort.Direction.ASC).on("age", Sort.Direction.ASC);indexName = mongoTemplate.indexOps(Student.class).ensureIndex(compoundIndex);Console.log(indexName);//3.创建多键值索引(tags列为字符串数组)Index multiKeyValueIndex = new Index().on("tags", Sort.Direction.DESC);indexName = mongoTemplate.indexOps(Student.class).ensureIndex(multiKeyValueIndex);Console.log(indexName);}
4.使用索引查询
单列索引,复合索引,多键值索引,hash索引
全文索引
与命令相同,包括find查询以及aggregate查询两种
使用TextCriteria来封装查询条件
//1.find查询List<Student> students = mongoTemplate.find(new Query(TextCriteria.forDefaultLanguage().matching("1")), Student.class);Assert.isTrue(1 == students.size());Assert.isTrue("1".equals(students.get(0).getId()));//2.聚合查询MatchOperation matchOperation = Aggregation.match(new TextCriteria().forDefaultLanguage().matching("1"));TypedAggregation<Student> typedAggregation = Aggregation.newAggregation(Student.class, matchOperation);AggregationResults<Student> aggregate = mongoTemplate.aggregate(typedAggregation, Student.class);Student result = aggregate.getUniqueMappedResult();Assert.isTrue("1".equals(result.getId()));
地理位置索引数据点示例
:::info
定义四个数据点(北京、大同、太原、湖南)
以北京为圆心
- 北京距离大同约等于300km
- 北京距离太原约等于500km
- 北京距离湖南约等于1750km
:::
2d平面-地理位置索引
实体类
```java import lombok.Data; import org.springframework.data.mongodb.core.index.CompoundIndex; import org.springframework.data.mongodb.core.index.CompoundIndexes; import org.springframework.data.mongodb.core.mapping.Document;
/**
- @author 冯铁城 [17615007230@163.com]
- @date 2022-07-25 20:18:40
@describe: */ @Data @Document(collection = “geo”) public class Flat {
private String id;
private String name;
private double[] loc; }
<a name="rL6Yg"></a>#### find查询find查询可以不指定maxDistance的单位。平面maxDistance默认单位为1度,1度约等于111km```java@Testvoid testSelect() {//1.定义平面坐标点List<Flat> flats = CollUtil.newArrayList();Flat flat = new Flat();flat.setName("北京");flat.setLoc(new double[]{115.25, 39.26});flats.add(flat);flat = new Flat();flat.setName("大同");flat.setLoc(new double[]{112.34, 39.03});flats.add(flat);flat = new Flat();flat.setName("太原");flat.setLoc(new double[]{111.3, 37.27});flats.add(flat);flat = new Flat();flat.setName("湖南");flat.setLoc(new double[]{108.47, 24.38});flats.add(flat);mongoTemplate.insert(flats, Flat.class);//3.全量查询,无最大距离Point point = new Point(115.28, 39.23);List<Flat> result = mongoTemplate.find(new Query(Criteria.where("loc").near(point)), Flat.class);Assert.isTrue(4 == result.size());//3.非全量查询,有最大距离point = new Point(115.28, 39.23);result = mongoTemplate.find(new Query(Criteria.where("loc").near(point).maxDistance(3)), Flat.class);Assert.isTrue(2 == result.size());}
geoNear查询
geoNear的优点是可以返回点之间的距离,也可以通过Metrics来指定maxDistance单位,如果不指定,默认单位为1度,约等于111km
geoNear返回的distance默认单位为km@Testvoid testSelect() {//1.定义平面坐标点List<Flat> flats = CollUtil.newArrayList();Flat flat = new Flat();flat.setName("北京");flat.setLoc(new double[]{115.25, 39.26});flats.add(flat);flat = new Flat();flat.setName("大同");flat.setLoc(new double[]{112.34, 39.03});flats.add(flat);flat = new Flat();flat.setName("太原");flat.setLoc(new double[]{111.3, 37.27});flats.add(flat);flat = new Flat();flat.setName("湖南");flat.setLoc(new double[]{108.47, 24.38});flats.add(flat);mongoTemplate.insert(flats, Flat.class);//2.定义圆心点Point point = new Point(115.28, 39.23);//3.全量查询,无最大距离NearQuery nearQuery = NearQuery.near(point);GeoResults<Flat> geoResults = mongoTemplate.geoNear(nearQuery, Flat.class);List<GeoResult<Flat>> content = geoResults.getContent();Assert.isTrue(4 == content.size());//4.非全量查询,有最大距离nearQuery = NearQuery.near(point).maxDistance(300, Metrics.KILOMETERS);geoResults = mongoTemplate.geoNear(nearQuery, Flat.class);content = geoResults.getContent();Assert.isTrue(2 == content.size());}
2dsphere球面-地理位置索引
实体类
球面索引的坐标点,建议用GeoJsonPoint来映射。因为2dsphere索引的列,值得类型允许经纬度数据或geoJson类型。建议使用geoJson类型 ```java import lombok.Data; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; import org.springframework.data.mongodb.core.mapping.Document;
/**
- @author 冯铁城 [17615007230@163.com]
- @date 2022-07-25 20:18:40
@describe: */ @Data @Document(collection = “geo”) public class Flat {
private String id;
private String name;
private GeoJsonPoint point; }
<a name="kgcOr"></a>#### find查询nearSphere可以进行球面查询,缺点是不能返回点之间的距离。球面索引默认maxDistance单位为1m```java@Testvoid testSelect() {//1.定义平面坐标点List<Flat> flats = CollUtil.newArrayList();Flat flat = new Flat();flat.setName("北京");flat.setPoint(new GeoJsonPoint(115.25, 39.26));flats.add(flat);flat = new Flat();flat.setName("大同");flat.setPoint(new GeoJsonPoint(112.34, 39.03));flats.add(flat);flat = new Flat();flat.setName("太原");flat.setPoint(new GeoJsonPoint(111.3, 37.27));flats.add(flat);flat = new Flat();flat.setName("湖南");flat.setPoint(new GeoJsonPoint(108.47, 24.38));flats.add(flat);mongoTemplate.insert(flats, Flat.class);//2.定义圆心点GeoJsonPoint point = new GeoJsonPoint(115.28, 39.23);//3.全量查询,无最大距离List<Flat> result = mongoTemplate.find(new Query(Criteria.where("point").nearSphere(point)), Flat.class);Assert.isTrue(4 == result.size());//4.非全量查询,有最大距离result = mongoTemplate.find(new Query(Criteria.where("point").nearSphere(point).maxDistance(300000)), Flat.class);Assert.isTrue(2 == result.size());}
geoNear查询
geoNear的优点是可以返回点之间的距离,也可以通过Metrics来指定maxDistance单位,如果不指定,默认单位为1m
geoNear返回的distance默认单位为km@Testvoid testSelect() {//1.定义平面坐标点List<Flat> flats = CollUtil.newArrayList();Flat flat = new Flat();flat.setName("北京");flat.setPoint(new GeoJsonPoint(115.25, 39.26));flats.add(flat);flat = new Flat();flat.setName("大同");flat.setPoint(new GeoJsonPoint(112.34, 39.03));flats.add(flat);flat = new Flat();flat.setName("太原");flat.setPoint(new GeoJsonPoint(111.3, 37.27));flats.add(flat);flat = new Flat();flat.setName("湖南");flat.setPoint(new GeoJsonPoint(108.47, 24.38));flats.add(flat);mongoTemplate.insert(flats, Flat.class);//2.定义圆心点GeoJsonPoint point = new GeoJsonPoint(115.28, 39.23);//3.全量查询,无最大距离NearQuery nearQuery = NearQuery.near(point);GeoResults<Flat> geoResults = mongoTemplate.geoNear(nearQuery, Flat.class);List<GeoResult<Flat>> content = geoResults.getContent();Assert.isTrue(4 == content.size());//4.非全量查询,有最大距离nearQuery = NearQuery.near(point).maxDistance(1800, Metrics.KILOMETERS);geoResults = mongoTemplate.geoNear(nearQuery, Flat.class);content = geoResults.getContent();Assert.isTrue(4 == content.size());//5.指定查询两点之间距离nearQuery = NearQuery.near(point).maxDistance(1800, Metrics.KILOMETERS).query(new Query(Criteria.where("name").is("湖南")));geoResults = mongoTemplate.geoNear(nearQuery, Flat.class);content = geoResults.getContent();Assert.isTrue(1 == content.size());Assert.isTrue("湖南".equals(content.get(0).getContent().getName()));System.out.println("北京到湖南之间的距离:" + content.get(0).getDistance().getValue());}
在规定球形范围内查询
@Testvoid testSelect() {//1.定义平面坐标点List<Flat> flats = CollUtil.newArrayList();Flat flat = new Flat();flat.setName("北京");flat.setPoint(new GeoJsonPoint(115.25, 39.26));flats.add(flat);flat = new Flat();flat.setName("大同");flat.setPoint(new GeoJsonPoint(112.34, 39.03));flats.add(flat);flat = new Flat();flat.setName("太原");flat.setPoint(new GeoJsonPoint(111.3, 37.27));flats.add(flat);flat = new Flat();flat.setName("湖南");flat.setPoint(new GeoJsonPoint(108.47, 24.38));flats.add(flat);mongoTemplate.insert(flats, Flat.class);//2.定义圆心点GeoJsonPoint point = new GeoJsonPoint(115.28, 39.23);//3.定义半径Distance distance = new Distance(300, Metrics.KILOMETERS);//4.绘制原型Circle circle = new Circle(point, distance);//5.查询List<Flat> results = mongoTemplate.find(new Query(Criteria.where("point").withinSphere(circle)), Flat.class);Assert.isTrue(2 == results.size());}
5.索引的特性
实体类
```java import lombok.Data; import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
/**
- @author 冯铁城 [17615007230@163.com]
- @date 2022-07-20 19:12:01
- @describe: MongoDB实体类
“@Document(collection = “student”)” 用于指定对应哪个集合 */ @Data @Document(collection = “student”) public class Student {
/**
主键ID */ private Integer id;
/**
学号 */ private String sno;
/**
名称 */ private String name;
/**
年龄 */ private Integer age;
/**
昵称 */ private String nikeName;
/**
描述 */ private String des;
/**
创建时间 */ private Date createTime; }
<a name="sQIln"></a>### 集合已创建<a name="qIihB"></a>### 唯一性设置并验证学号:unique唯一性```java@Testvoid testUnique() {//1.创建学号唯一索引Index snoIndex = new Index().on("sno", Sort.Direction.ASC).unique();mongoTemplate.indexOps(Student.class).ensureIndex(snoIndex);//2.保存数据Student student = new Student();student.setId(1);student.setSno("1");mongoTemplate.insert(student);//3.再次保存数据student = new Student();student.setId(2);student.setSno("1");try{mongoTemplate.insert(student);}catch (Exception e){Assert.isTrue(e.getMessage().contains("java_test.student index: sno_1 dup key: { sno: \"1\" }"));}}
稀疏性设置并验证
昵称:sparse稀疏性
@Testvoid testSparse() {//1.创建昵称唯一索引Index nikeNameIndex = new Index().on("nikeName", Sort.Direction.ASC).unique();String indexName = mongoTemplate.indexOps(Student.class).ensureIndex(nikeNameIndex);//2.保存数据Student student = new Student();student.setId(1);student.setNikeName("xxx1");mongoTemplate.insert(student);//3.保存1条不包含昵称的数据student = new Student();student.setId(2);mongoTemplate.insert(student);//4.再次保存1条不包含昵称的数据student = new Student();student.setId(3);try {mongoTemplate.insert(student);} catch (Exception e) {Assert.isTrue(e.getMessage().contains("nikeName_1 dup key: { nikeName: null }"));}//5.重新创建索引设置唯一性和稀疏性mongoTemplate.indexOps(Student.class).dropIndex(indexName);nikeNameIndex = new Index().on("nikeName", Sort.Direction.ASC).unique().sparse();mongoTemplate.indexOps(Student.class).ensureIndex(nikeNameIndex);//6.再次保存2条不包含昵称的数据,无异常抛出student = new Student();student.setId(3);mongoTemplate.insert(student);student = new Student();student.setId(4);mongoTemplate.insert(student);}
部分性设置并验证
年龄:partial部分性
@Testvoid testPartial() {//1.设置索引Index ageIndex = new Index().on("age", Sort.Direction.ASC).partial(PartialIndexFilter.of(Criteria.where("age").gt(6)));//2.创建索引mongoTemplate.indexOps(Student.class).ensureIndex(ageIndex);}
具体代码怎么验证暂时没想到,从命令行查询,如图,age字段部分索引创建成功
TTL性设置并验证
@Testvoid testTtl() {//1.设置ttl索引Index createTimeIndex = new Index().on("createTime", Sort.Direction.ASC).expire(10, TimeUnit.SECONDS);mongoTemplate.indexOps(Student.class).ensureIndex(createTimeIndex);//2.存入数据Student student = new Student();student.setId(1);student.setCreateTime(new Date());//3.沉睡10s钟try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}//4.再次查询Student result = mongoTemplate.findOne(new Query(), Student.class);Assert.isNull(result);}
