MongoDB:SpringBoot有關@Document(collection = "")與@Document(collation= "")註解的區別

 

目錄

 

QUESTION:SpringBoot有關@Document(collection = "")與@Document(collation= "")註解的區別?

ANSWER:

一、問題原因

二、分析

2.1 Collection

@Id

@Document

@Indexed

@CompoundIndex

@Field

@Transient

@DBRef

2.2 Collation

2.2.1特性

2.2.2示例

轉載博客出處:

 


 

 

QUESTION:SpringBoot有關@Document(collection = "")與@Document(collation= "")註解的區別?

 

ANSWER:

在啓動項目時,報出如下異常:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'messageDaoImpl': Unsatisfied dependency expressed through field 'mongoTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDbFactoryDependentConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.core.MongoTemplate]: Factory method 'mongoTemplate' threw exception; nested exception is org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 2 (BadValue): 'failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: "status", ns: "testdb.message", collation: { locale: "message" } } :: caused by :: Field 'locale' is invalid in: { locale: "message" }' on server www.youngxy.top:27018. The full response is {"ok": 0.0, "errmsg": "failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: \"status\", ns: \"testdb.message\", collation: { locale: \"message\" } } :: caused by :: Field 'locale' is invalid in: { locale: \"message\" }", "code": 2, "codeName": "BadValue"}; nested exception is com.mongodb.MongoCommandException: Command failed with error 2 (BadValue): 'failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: "status", ns: "testdb.message", collation: { locale: "message" } } :: caused by :: Field 'locale' is invalid in: { locale: "message" }' on server www.youngxy.top:27018. The full response is {"ok": 0.0, "errmsg": "failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: \"status\", ns: \"testdb.message\", collation: { locale: \"message\" } } :: caused by :: Field 'locale' is invalid in: { locale: \"message\" }", "code": 2, "codeName": "BadValue"}
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.4.RELEASE.jar:2.2.4.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.4.RELEASE.jar:2.2.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.4.RELEASE.jar:2.2.4.RELEASE]
	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:126) [spring-boot-test-2.2.4.RELEASE.jar:2.2.4.RELEASE]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) [spring-test-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) [spring-test-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123) [spring-test-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) [spring-test-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) [spring-test-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244) [spring-test-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:98) [spring-test-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$5(ClassBasedTestDescriptor.java:337) [junit-jupiter-engine-5.5.2.jar:5.5.2]
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:342) [junit-jupiter-engine-5.5.2.jar:5.5.2]
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$6(ClassBasedTestDescriptor.java:337) [junit-jupiter-engine-5.5.2.jar:5.5.2]
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_202]
	at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) ~[na:1.8.0_202]
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[na:1.8.0_202]
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_202]
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_202]
	at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312) ~[na:1.8.0_202]
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743) ~[na:1.8.0_202]
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742) ~[na:1.8.0_202]
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) ~[na:1.8.0_202]
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:336) [junit-jupiter-engine-5.5.2.jar:5.5.2]
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:259) [junit-jupiter-engine-5.5.2.jar:5.5.2]
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$2(ClassBasedTestDescriptor.java:252) [junit-jupiter-engine-5.5.2.jar:5.5.2]
	at java.util.Optional.orElseGet(Optional.java:267) ~[na:1.8.0_202]
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$3(ClassBasedTestDescriptor.java:251) [junit-jupiter-engine-5.5.2.jar:5.5.2]
	at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:29) ~[junit-jupiter-engine-5.5.2.jar:5.5.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:106) ~[junit-jupiter-engine-5.5.2.jar:5.5.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:105) ~[junit-jupiter-engine-5.5.2.jar:5.5.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:69) ~[junit-jupiter-engine-5.5.2.jar:5.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:107) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:107) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:75) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_202]
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_202]
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) ~[junit-platform-engine-1.5.2.jar:1.5.2]
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229) ~[junit-platform-launcher-1.5.2.jar:1.5.2]
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197) ~[junit-platform-launcher-1.5.2.jar:1.5.2]
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211) ~[junit-platform-launcher-1.5.2.jar:1.5.2]
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191) ~[junit-platform-launcher-1.5.2.jar:1.5.2]
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) ~[junit-platform-launcher-1.5.2.jar:1.5.2]
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69) ~[junit5-rt.jar:na]
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) ~[junit-rt.jar:na]
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230) ~[junit-rt.jar:na]
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58) ~[junit-rt.jar:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDbFactoryDependentConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.core.MongoTemplate]: Factory method 'mongoTemplate' threw exception; nested exception is org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 2 (BadValue): 'failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: "status", ns: "testdb.message", collation: { locale: "message" } } :: caused by :: Field 'locale' is invalid in: { locale: "message" }' on server www.youngxy.top:27018. The full response is {"ok": 0.0, "errmsg": "failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: \"status\", ns: \"testdb.message\", collation: { locale: \"message\" } } :: caused by :: Field 'locale' is invalid in: { locale: \"message\" }", "code": 2, "codeName": "BadValue"}; nested exception is com.mongodb.MongoCommandException: Command failed with error 2 (BadValue): 'failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: "status", ns: "testdb.message", collation: { locale: "message" } } :: caused by :: Field 'locale' is invalid in: { locale: "message" }' on server www.youngxy.top:27018. The full response is {"ok": 0.0, "errmsg": "failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: \"status\", ns: \"testdb.message\", collation: { locale: \"message\" } } :: caused by :: Field 'locale' is invalid in: { locale: \"message\" }", "code": 2, "codeName": "BadValue"}
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	... 81 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.core.MongoTemplate]: Factory method 'mongoTemplate' threw exception; nested exception is org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 2 (BadValue): 'failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: "status", ns: "testdb.message", collation: { locale: "message" } } :: caused by :: Field 'locale' is invalid in: { locale: "message" }' on server www.youngxy.top:27018. The full response is {"ok": 0.0, "errmsg": "failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: \"status\", ns: \"testdb.message\", collation: { locale: \"message\" } } :: caused by :: Field 'locale' is invalid in: { locale: \"message\" }", "code": 2, "codeName": "BadValue"}; nested exception is com.mongodb.MongoCommandException: Command failed with error 2 (BadValue): 'failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: "status", ns: "testdb.message", collation: { locale: "message" } } :: caused by :: Field 'locale' is invalid in: { locale: "message" }' on server www.youngxy.top:27018. The full response is {"ok": 0.0, "errmsg": "failed to add collation information to index spec for index creation: { v: 2, key: { status: 1 }, name: \"status\", ns: \"testdb.message\", collation: { locale: \"message\" } } :: caused by :: Field 'locale' is invalid in: { locale: \"message\" }", "code": 2, "codeName": "BadValue"}

一、問題原因

經查找,'failed to add collation information to index spec for index creation:是指出了異常的問題。

在一個實體類中使用了:

@Document(collation = "message")

這裏應該變爲:

@Document(collection = "message")

二、分析

這裏區分一下兩者的區別:

2.1 Collection

 

@Id


主鍵,不可重複,自帶索引,可以在定義的列名上標註,需要自己生成並維護不重複的約束。如果自己不設置@Id主鍵,mongo會自動生成一個唯一主鍵,並且插入時效率遠高於自己設置主鍵。原因可參考上一篇mongo和mysql的性能對比。 
在實際業務中不建議自己設置主鍵,應交給mongo自己生成,自己可以設置一個業務id,如int型字段,用自己設置的業務id來維護相關聯的表。

@Document


標註在實體類上,類似於hibernate的entity註解,標明由mongo來維護該表。

org.springframework.data.mongodb.core.mapping.Document.class
把一個java類聲明爲mongodb的文檔,可以通過collection參數指定這個類對應的文檔。
@Document(collection="mongodb 對應 collection 名")      

// 若未加 @Document ,該 bean save 到 mongo 的 user collection
// 若添加 @Document ,則 save 到 reUser collection

org.springframework.data.mongodb.core.mapping.Document.class
把一個java類聲明爲mongodb的文檔,可以通過collection參數指定這個類對應的文檔。
@Document(collection="mongodb 對應 collection 名")      

// 若未加 @Document ,該 bean save 到 mongo 的 user collection
// 若添加 @Document ,則 save 到 reUser collection
@Document(collection="reUser") 
public class User{
}


@Indexed


聲明該字段需要加索引,加索引後以該字段爲條件檢索將大大提高速度。 
唯一索引的話是@Indexed(unique = true)。 
也可以對數組進行索引,如果被索引的列是數組時,MongoDB會索引這個數組中的每一個元素。 
也可以對整個Document進行索引,排序是預定義的按插入BSON數據的先後升序排列。 
也可以對關聯的對象的字段進行索引,譬如User對關聯的address.city進行索引。(註解怎麼寫還不清楚,待查)

@CompoundIndex


複合索引,加複合索引後通過複合索引字段查詢將大大提高速度。

@Document
@CompoundIndexes({
    @CompoundIndex(name = "age_idx", def = "{'lastName': 1, 'age': -1}")
})
public class Person<T extends Address> {
}


寫法如上,lastName和age將作爲複合索引,數字參數指定索引的方向,1爲正序,-1爲倒序。方向對單鍵索引和隨機存不要緊,但如果你要執行分組和排序操作的時候,它就非常重要了。

@Field


代表一個字段,可以不加,不加的話默認以參數名爲列名。

給映射存儲到 mongodb 的字段取別名
在 java bean 中字段名爲 firstName,存儲到 mongo 中 key 爲 fName
   

給映射存儲到 mongodb 的字段取別名
在 java bean 中字段名爲 firstName,存儲到 mongo 中 key 爲 fName
    @Field("fName")
    private String firstName; 


@Transient


被該註解標註的,將不會被錄入到數據庫中。只作爲普通的javaBean屬性。

@DBRef

 


關聯另一個document對象。類似於mysql的表關聯,但並不一樣,mongo不會做級聯的操作。 
先來看一下不加DBRef時,mongo保存數據的情況: 
Article類有String title,List pictureList,兩個屬性,Picture有一個url,一個desc屬性。新建數個Picture對象,並賦值給Article的list,執行Article的insert操作,mongo保存的結果如圖: 


 
list會作爲普通的數據存到article裏,並不會爲Picture建表,這一點是區別於mysql的級聯存儲的。

在Article裏給list加上DBRef註解後就不同了 


 
再次執行添加Article操作後,看結果 


 
發現就不再是直接顯示的Picture的各個屬性了,而是隻保存了Picture的id和namespace,同時仍然沒有創建Picture的collection(等同於mysql的表)。 
如此此時查詢該Article,會發現list爲空,並沒有關聯上Picture的值。其實上一步已經發現了,系統並沒有去創建Picture的表。那即便Article關聯了PictureList的id,也是無法查詢的。 


官方解釋: 
The mapping framework does not handle cascading saves. If you change an Account object that is referenced by a Person object, you must save the Account object separately. Calling save on the Person object will not automatically save the Account objects in the property accounts.意思就是不會處理級聯保存,你必須單獨處理關聯的對象。 
現在修改一下添加Article的代碼,先做Picture的持久化操作。 


 
再看結果,發現Picture已經被持久化,再次查詢該Article時,相應的Picture也全部查了出來。 
如果在Article裏刪除關聯的list,set爲null並保存,系統只會刪掉Article裏關聯的list,而Picture對象本身的數據是不會被刪除的。 
從上面看來,貌似DBRef比較雞肋,而且甚至有時還會帶着誤導的性質,譬如Article關聯了兩個空的Picture時在Article還能看到2個對象的引用,然後2個對象並不存在,是查詢不出來的。 
那麼這個標籤存在的意義何在?

官方的說法是: 
In short,the best time to use DBRefs are when you’re storing heterogeneous references to documents in different collections.like when you want to take advantage of some additional DBRef-specific 
functionality in a driver or tool. 

實際使用中,感覺貌似作用是在不同的表做劃分吧,有點模擬mysql外鍵的意思。免得數據都落到一個大表的,不便於做關聯的表的查詢。

 

 

2.2 Collation

 

2.2.1特性

Collation的3.4版本新特性。
拼寫允許用戶在字符串比較中使用特殊語言-特殊規則,例如字母拼寫和口音標記規則。
你可以爲一個收藏或視圖、索引或支持拼寫的具體操作做特色拼寫。
一份拼寫文件有以下字段:

{
   locale: <string>,
   caseLevel: <boolean>,
   caseFirst: <string>,
   strength: <int>,
   numericOrdering: <boolean>,
   alternate: <string>,
   maxVariable: <string>,
   backwards: <boolean>
}

 

當具體的拼寫時,當地的拼寫是強制性的;所有其他拼寫是可選的。點擊查看官方文檔:see collation document.

2.2.2示例

db.createCollection("person")
db.person.insert({name: "張三"})
db.person.insert({name: "李四"})
db.person.insert({name: "王五"})
db.person.insert({name: "馬六"})
db.person.insert({name: "張七"})

默認情況下,名字字段會被當做一個普通的二機制字符串來對比,按照name字段排序的結果如下

mongo-9554:PRIMARY&gt; db.person.find().sort({name: 1})
{ "_id" : ObjectId("586b98980cec8d86881cffac"), "name" : "張七" }
{ "_id" : ObjectId("586b98980cec8d86881cffa8"), "name" : "張三" }
{ "_id" : ObjectId("586b98980cec8d86881cffa9"), "name" : "李四" }
{ "_id" : ObjectId("586b98980cec8d86881cffaa"), "name" : "王五" }
{ "_id" : ObjectId("586b98980cec8d86881cffab"), "name" : "馬六" }

而對於中文名字,通常有按拼音順序排序的需求,這時就可以通過collation來搞定

db.createCollection("person", {collation: {locale: "zh"}})
db.person.insert({name: "張三"})
db.person.insert({name: "李四"})
db.person.insert({name: "王五"})
db.person.insert({name: "馬六"})
db.person.insert({name: "張七"})

此時再按name字段排序,則會按照locale指定的中文規則來排序

mongo-9554:PRIMARY&gt; db.person.find().sort({name: 1})
{ "_id" : ObjectId("586b995d0cec8d86881cffae"), "name" : "李四" }
{ "_id" : ObjectId("586b995d0cec8d86881cffb0"), "name" : "馬六" }
{ "_id" : ObjectId("586b995d0cec8d86881cffaf"), "name" : "王五" }
{ "_id" : ObjectId("586b995d0cec8d86881cffb1"), "name" : "張七" }
{ "_id" : ObjectId("586b995d0cec8d86881cffad"), "name" : "張三" }

MongoDB 3.4裏,基本所有設計字符串字段排序的命令,都支持指定collation,比如「創建集合、創建索引、find」等;上述例子裏在createCollection的時候指定了collation,則該集合裏所有字符串默認都會按指定的collation來排序,如果只想針對某一個字段來指定collation,可以該字段創建指定collation的索引,例如

db.person.createIndex({name: 1}, {collation: {locale: "zh"}})

注意:如果是從3.2版本升級到3.4的,需要先執行如下命令才能使用collation特性

db.adminCommand( { setFeatureCompatibilityVersion: "3.4" } )

 

轉載博客出處:

SpringBoot中MongoDB註解概念及使用

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章