【问题标题】:MongoDB find does not follow collation ruleMongoDB 查找不遵循排序规则
【发布时间】:2020-09-22 01:52:38
【问题描述】:

我想在 membershipAccount 集合上创建一个索引,该集合有一个排序规则集,允许 find 方法在不区分大小写的情况下找到 username

[
    2,
    {
        "username" : 1.0
    },
    "username_1",
    "kollecto_prod.membershipAccounts",
    {
        "locale" : "da",
        "caseLevel" : false,
        "caseFirst" : "off",
        "strength" : 1,
        "numericOrdering" : false,
        "alternate" : "non-ignorable",
        "maxVariable" : "punct",
        "normalization" : false,
        "backwards" : false,
        "version" : "57.1"
    }
]

我的membershipAccountscollection 中有一个名为user@test.com 的用户。 但这是我查找查询的结果:

db.getCollection('membershipAccounts').find({username: "user@test.com"}) // 1 result - ok
db.getCollection('membershipAccounts').find({username: "USER@test.com"}) // 0 results - nope
db.getCollection('membershipAccounts').find({username: "USER@TEST.com"}) // 0 results - nope
db.getCollection('membershipAccounts').find({username: "USER@TEST.COM"}) // 0 results - nope

我的排序规则不正确还是我误解了这个概念?

【问题讨论】:

    标签: json mongodb collation bson


    【解决方案1】:

    您需要在查询中设置所需的排序规则,或者在集合上设置默认排序规则。使用排序规则创建索引不会使该排序规则成为查询中使用的默认排序规则。

    每个查询:

    MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.insert({v:'test'})
    WriteResult({ "nInserted" : 1 })
    MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find({v:'TEST'}).collation({locale:'en',caseLevel:false,strength:1})
    { "_id" : ObjectId("5ed8302ba6de3bc31c771682"), "v" : "test" }
    

    默认排序规则:

    MongoDB Enterprise ruby-driver-rs:PRIMARY> c={locale:'en',caseLevel:false,strength:1}
    { "locale" : "en", "caseLevel" : false, "strength" : 1 }
    MongoDB Enterprise ruby-driver-rs:PRIMARY> db.createCollection('bar',{collation:c})
    {
            "ok" : 1,
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1591226649, 1),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            },
            "operationTime" : Timestamp(1591226649, 1)
    }
    MongoDB Enterprise ruby-driver-rs:PRIMARY> db.bar.insert({v:'test'})
    WriteResult({ "nInserted" : 1 })
    MongoDB Enterprise ruby-driver-rs:PRIMARY> db.bar.find({v:'TEST'})
    { "_id" : ObjectId("5ed8311fa6de3bc31c771683"), "v" : "test" }
    

    【讨论】:

    • 是的 - 这也是我发现的。但是一旦创建了一个集合,目前就无法更改该集合的默认排序规则。这很糟糕。
    • 您可以尝试使用相同的数据和所需的新默认排序规则创建一个新集合,然后重命名该集合。
    【解决方案2】:

    所以我最终做的是在我的代码中如下:

    var account = DBHelper.membershipAccountCollection.Find(
        x => x.Username.ToLower().Contains(username)
    ).FirstOrDefault();
    
    var cu = DBHelper.customerUserCollection.AsQueryable().First(
        x => x.Email.ToLower().Contains(model.UserName)
    );
    

    这是可行的,因为我的 C# 代码中已经有了集合对象,所以我可以通过这种方式利用 C# 的强大功能。我意识到这不是对整个问题的一般答案,但它适用于我的情况。如果有人对这个问题有更笼统的答案,我很乐意在以后接受这个答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多