Mongo唯一索引不区分大小写

Posted

技术标签:

【中文标题】Mongo唯一索引不区分大小写【英文标题】:Mongo unique index case insensitive 【发布时间】:2016-02-17 14:23:07 【问题描述】:
@CompoundIndexes(
    @CompoundIndex(name = "fertilizer_idx",
        unique = true,
        def = "'name': 1, 'formula': 1, 'type': 1")
)
public class Fertilizer extends Element implements Serializable 
//class stuff

是否可以创建不区分大小写的索引?现在它正在从NAME 区分为NAMe。保存第二个字段小写(或大写)对我来说是不可能的。

谢谢, 佩德罗

【问题讨论】:

你到现在有没有得到什么?? 【参考方案1】:

MongoDB 版本 3.4 之前,我们无法创建 不区分大小写index

在 3.4 版中具有collation 选项,允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音标记的规则。

排序规则选项的语法如下:

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

locale 字段为必填;所有其他字段可选

要创建不区分大小写的索引,我们需要使用强制字段 localestrength 字段来进行字符串比较级别。 strength 允许值范围 1 - 5。 read more about collation

strength 属性决定在整理或匹配文本时是否考虑重音或大小写

示例:

如果 strength=1 那么 role = Role = 角色

如果 strength=2 那么 role = Role

如果 strength=3 那么 role

Comparison level doc

所以我们需要使用strength=2来创建索引。喜欢:

db.collectionName.createIndex(
   name: 1, formula: 1, type: 1 ,
   
    name: "fertilizer_idx",
    collation: locale: "en", strength: 2,
    unique: true
  
)

注意collation 选项不适用于 文本 索引。

【讨论】:

注意:这在 DocDB 3.6.0 版本的 Amazon DocumentDB 中不起作用,因为不支持排序规则游标。见docs.aws.amazon.com/documentdb/latest/developerguide/…【参考方案2】:

是的,现在 MongoDB 3.4 中提供了新的排序规则功能。

你可以像这样创建一个不区分大小写的索引:

db.collection.createIndex(
   name:1,
   formula:1,
   type:1
,

   collation:
      locale:"en",
      strength:2
   
);

其中强度属性是比较级别

然后您可以使用此查询获得不区分大小写的匹配:

db.collection.find(name: "name").collation(locale: "en", strength: 2);

详情请见collation

如果你从以前的版本升级到 mongodb 3.4,你可能需要在创建索引之前设置兼容性

db.adminCommand(  setFeatureCompatibilityVersion: "3.4"  )

【讨论】:

【参考方案3】:
db.collection.createIndex(
 name: 1, formula: 1, type: 1 ,
 name: "fertilizer_idx", unique: true, collation: locale: "en", strength: 2  
)

使用排序规则作为 db.collection.createIndex() 的一个选项

更多信息在这里: https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/

在此处获取区域设置/语言信息: https://docs.mongodb.com/manual/reference/collation-locales-defaults/#collation-languages-locales

强度:整数

可选。要执行的比较级别。可能的值是:

1:比较的初级水平。 Collat​​ion 仅执行基本字符的比较,忽略其他差异,例如变音符号和大小写。

2:二级比较。 Collat​​ion 执行直到次要差异的比较,例如变音符号。也就是说,排序规则执行基本字符(主要差异)和变音符号(次要差异)的比较。基本字符之间的差异优先于次要差异。

3:第三级比较。 Collat​​ion 执行直到三级差异的比较,例如大小写和字母变体。也就是说,排序规则执行基本字符(主要差异)、变音符号(次要差异)以及大小写和变体(三次差异)的比较。基本字符之间的差异优先于二级差异,二级差异优先于三级差异。 这是默认级别。

4:第四级。仅限于在 1-3 级忽略标点符号或处理日语文本时考虑标点符号的特定用例。

5:相同级别。仅限于决胜局的特定用例。

Mongo 3.4 有排序规则,允许用户指定特定语言的字符串比较规则

整理包括:

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

【讨论】:

【参考方案4】:

Spring Data Mongo2.2 提供'通过@Document 和@Query 支持基于Annotation 的排序规则。'

参考。 What's new in Spring Data Mongo2.2

@Document(collection = 'fertilizer', collation = "'locale':'en', 'strength':2")
public class Fertilizer extends Element implements Serializable 

    @Indexed(unique = true)
    private String name;
    //class stuff

当应用程序启动时,它将为每个文档创建索引以及相应的排序规则。

【讨论】:

【参考方案5】:

正如 Shaishab Roy 所述,您应该使用 collat​​ion.strength

没有办法用spring数据的注释来定义它

您可以手动实现它。要在您的 Spring 应用程序中实现此行为,您应该创建事件侦听器以侦听您的应用程序已准备好,注入 MongoOperations bean 并定义索引,如下例所示:

@Configuration
public class MongoConfig 
  @Autowired
  private MongoOperations mongoOperations;

  @EventListener(ApplicationReadyEvent.class)
  public void initMongo() 
    mongoOperations
    .indexOps(YourCollectionClass.class)
    .ensureIndex(
        new Index()
            .on("indexing_field_name", Sort.Direction.ASC)
            .unique()
            .collation(Collation.of("en").strength(2)));
  

【讨论】:

以上是关于Mongo唯一索引不区分大小写的主要内容,如果未能解决你的问题,请参考以下文章

Mongo中不区分大小写的搜索

PostgreSQL 唯一索引和字符串大小写

MySQL / MariaDB 不区分大小写的排序规则仍然区分大小写吗?

如何使字段不区分大小写且唯一?

Mongoose 模式:验证唯一字段,不区分大小写

Mongoose 模式:验证唯一字段,不区分大小写