如何忽略DocumentContent中要保存在MongoDB中的“ $”?

时间:2018-09-18 15:02:33

标签: mongodb

我的问题是,如果我在内容中保存带有$的文档,Mongodb会给我一个例外:

  

java.lang.IllegalArgumentException:无效的BSON字段名称$ xxx

我希望mongodb忽略内容中的$字符。

我的应用程序是用Java编写的。我读取了文件的内容,并将其作为字符串放入对象中。之后,该对象将与MongoRepository类一起保存。

有人有什么想法吗?

Example content

编辑:听说mongodb有相同的问题,包括点。我们的Springboot发现我可以用点来解决,但不能解决美元问题。

How to configure mongo converter in spring to encode all dots in the keys of map being saved in mongo db

1 个答案:

答案 0 :(得分:0)

如果您使用的是Spring Boot,则可以扩展MappingMongoConverter类并添加进行转义/转义的重写方法。

@Component
public class MappingMongoConverterCustom extends MappingMongoConverter {

    protected @Nullable
    String mapKeyDollarReplacemant = "characters_to_replace_dollar";

    protected @Nullable
    String mapKeyDotReplacement = "characters_to_replace_dot";

    public MappingMongoConverterCustom(DbRefResolver dbRefResolver, MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
        super(dbRefResolver, mappingContext);
    }

    @Override
    protected String potentiallyEscapeMapKey(String source) {
        if (!source.contains(".") && !source.contains("$")) {
            return source;
        }

        if (mapKeyDotReplacement == null && mapKeyDollarReplacemant == null) {
            throw new MappingException(String.format(
                    "Map key %s contains dots or dollars but no replacement was configured! Make "
                            + "sure map keys don't contain dots or dollars in the first place or configure an appropriate replacement!",
                    source));
        }

        String result = source;
        if(result.contains(".")) {
            result = result.replaceAll("\\.", mapKeyDotReplacement);
        }
        if(result.contains("$")) {
            result = result.replaceAll("\\$", mapKeyDollarReplacemant);
        }
        
        //add any other replacements you need

        return result;
    }

    @Override
    protected String potentiallyUnescapeMapKey(String source) {
        String result = source;
        if(mapKeyDotReplacement != null) {
            result = result.replaceAll(mapKeyDotReplacement, "\\.");
        }
        if(mapKeyDollarReplacemant != null) {
            result = result.replaceAll(mapKeyDollarReplacemant, "\\$");
        }
        
         //add any other replacements you need
        return result;
    }
}

如果采用这种方法,请确保从AbstractMongoConfiguration覆盖默认的转换器,如下所示:

@Configuration
public class MongoConfig extends AbstractMongoConfiguration{

@Bean
public DbRefResolver getDbRefResolver() {
    return new DefaultDbRefResolver(mongoDbFactory());
}

@Bean
@Override
public MappingMongoConverter mappingMongoConverter() throws Exception {
    MappingMongoConverterCustom converter = new MappingMongoConverterCustom(getDbRefResolver(), mongoMappingContext());
    converter.setCustomConversions(customConversions());

    return converter;
}

   .... whatever you might need extra ...
}