经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MongoDB » 查看文章
mongo数据集合属性中存在点号(.)
来源:cnblogs  作者:鸡犬相闻  时间:2018/10/10 8:57:11  对本文有异议

基本知识点:

1.似乎mongo3.6之前不允许插入带点(.)或美元符号($)的键,但是当我使用mongoimport工具导入包含点的JSON文件时,它工作正常。

2.在使用spring-data-mongodb处理mongodb的增删改查时会通过一个MappingMongoConverter(Document和Modle转换类)转换数据

3.具体对点号的转换在DBObjectAccessor(spring-data-mongodb-1.10.13)或者DocumentAccessor(spring-data-mongodb-2.0.9),如下:

  1. //插入时转换public void put(MongoPersistentProperty prop, Object value) {
  2.     Assert.notNull(prop, "MongoPersistentProperty must not be null!");
  3.     String fieldName = prop.getFieldName();if (!fieldName.contains(".")) {
  4.         dbObject.put(fieldName, value);return;
  5.     }
  6.     Iterator<String> parts = Arrays.asList(fieldName.split("\\.")).iterator();
  7.     DBObject dbObject = this.dbObject;while (parts.hasNext()) {
  8.         String part = parts.next();if (parts.hasNext()) {
  9.             dbObject = getOrCreateNestedDbObject(part, dbObject);
  10.         } else {
  11.             dbObject.put(part, value);
  12.         }
  13.     }
  14. }//查询时转换public Object get(MongoPersistentProperty property) {
  15.     String fieldName = property.getFieldName();if (!fieldName.contains(".")) {return this.dbObject.get(fieldName);
  16.     }
  17.     Iterator<String> parts = Arrays.asList(fieldName.split("\\.")).iterator();
  18.     Map<String, Object> source = this.dbObject;
  19.     Object result = null;while (source != null && parts.hasNext()) {
  20.         result = source.get(parts.next());if (parts.hasNext()) {
  21.             source = getAsMap(result);
  22.         }
  23.     }return result;
  24. }//判断值是否为空public boolean hasValue(MongoPersistentProperty property) {
  25.     Assert.notNull(property, "Property must not be null!");
  26.     String fieldName = property.getFieldName();if (!fieldName.contains(".")) {return this.dbObject.containsField(fieldName);
  27.     }
  28.     String[] parts = fieldName.split("\\.");
  29.     Map<String, Object> source = this.dbObject;
  30.     Object result = null;for (int i = 1; i < parts.length; i++) {
  31.         result = source.get(parts[- 1]);
  32.         source = getAsMap(result);if (source == null) {return false;
  33.         }
  34.     }return source.containsKey(parts[parts.length - 1]);
  35. }

 

4.点号在mongodb中有子集合的含义

例如查询A.B属性:查询的是集合中A对应子集合中的属性B的值,并不是查询集合中A.B的属性  

问题描述:文档在数据库中的样子:

  1. {
  2.     "_id": ObjectId("5bae00765500af6307755111"),
  3.     "name": "java",
  4.     "age": 26,
  5.     "A.B": "nnnn"
  6. }

 

  1. 因此在Model中使用@Field("A.B")查询不出集合中的"A.B"的值
  2. @Field("A.B")
  3. @JSONField(serialzeFeatures = SerializerFeature.DisableCircularReferenceDetect)
  4. private Integer ab;  

5.解决方法:

查阅多方资料有以下几点体会:点号在MongoDB中可以插入应该开始于3.6版本,官方文档虽然说可以支持点号,但是第三方驱动、spring-data-mongodb并没有支持,但是因为一开始项目已经使用了spring-data-mongodb难以替换,所以就想到覆盖转换方法。

怎么覆盖spring-data-mongodb包中的文件?

新建一个和DBObjectAccessor转换文件一样的目录,重新建DBObjectAccessor类复制代码自定义修改,编译之后或优先使用新建的类。

  1. //查询时转换
  2. public Object get(MongoPersistentProperty property) {
  3.     String fieldName = property.getFieldName();
  4.     return this.dbObject.get(fieldName);
  5. }
  6.  
  7. //判断值是否为空
  8. public boolean hasValue(MongoPersistentProperty property) {
  9.     Assert.notNull(property, "Property must not be null!");
  10.     String fieldName = property.getFieldName();
  11.     return this.dbObject.containsField(fieldName);
  12. }  

 

 注意:尽量不要修改put方法,应为低版本的MongoDB本不支持点号,插入会报错 

 当然最好不要发生属性中有点号的情况。

 

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号