目錄
QUESTION:SpringBoot有關@Document(collection = "")與@Document(collation= "")註解的區別?
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> 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> 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" } )
轉載博客出處: