【问题标题】:MongoDB C# Case Insensitive Sort and IndexMongoDB C# 不区分大小写的排序和索引
【发布时间】:2019-06-29 07:50:47
【问题描述】:

到目前为止,我一直在使用此代码来查找我的文档,然后对其进行排序:

        var options = new FindOptions
        {
            Modifiers = new BsonDocument("$hint", "PathTypeFilenameIndex")
        };

        return await Collection
            .Find(f => f.Metadata["path"] == path, options)
            .SortBy(f => f.Metadata["type"])
            .ThenBy(f => f.Filename)
            .ToListAsync();

我有一个包含路径和类型字段的元数据字段的类,该类还有一个文件名字段。我希望元数据中具有给定路径的所有文档按类型排序,然后按文件名排序。

一个示例结果是按名称字段排序的文档列表,如下所示:

a, Ab, B, c, D

不幸的是,我得到了这样的东西:

Ab, B, D, a, c

这是因为 MongoDB 使用简单的二进制比较对数据进行排序,其中 'A'

所以我的问题是:有没有办法进行不区分大小写的排序并继续使用“$hint”?

我传递给 Find 方法的选项应该告诉 MongoDB 使用哪个索引。我找到了这篇文章:MongoDB and C#: Case insensitive search 但这里的方法不适用于排序,我无法告诉 MongoDB 使用哪个索引。

【问题讨论】:

    标签: c# mongodb sorting indexing


    【解决方案1】:

    我认为您可以将聚合管道与$addFields$toLower(在临时字段中将文件名转换为小写)和$sort 一起使用,以不分大小写对它们进行排序

    在 mongodb shell 中你会这样写:

    db.collection.aggregate([{
        $addFields : {
            "lowercaseFileName" : {
                $loLower : "$fileName"
            }
        },{
            $sort : {
                "metadata.type" : 1,
                lowercaseFileName : 1
            }
        }
    }])
    

    请用c#编写类似的代码,看看是否有效。我不知道 c#,否则我会给你确切的查询,但我不能。

    想法是将文件名转换为小写,将其保存在临时字段中,使用 addFields 并按该字段排序。

    希望对你有所帮助。

    在此处阅读有关$addFields$toLower 的更多信息。

    更新

    感谢@kaloyan-manev

    你可以用这个:

    return await Collection.Aggregate()
        .Match(f => f.Metadata["path"] == path) 
        .AppendStage<BsonDocument>(new BsonDocument("$addFields", new BsonDocument("lowercaseFileName", new BsonDocument("$toLower", "$filename")))) 
        .AppendStage<GridFSFileInfo>(new BsonDocument("$sort", new BsonDocument { {"metadata.type", 1}, {"lowercaseFileName", 1} }))
        .ToListAsync();
    

    【讨论】:

    • 谢谢,我会试试的,我会回信的。
    • 如果需要,可以将此代码添加到您的答案中: return await Collection.Aggregate() .Match(f => f.Metadata["path"] == path) .AppendStage(new BsonDocument("$addFields", new BsonDocument("lowercaseFileName", new BsonDocument("$toLower", "$filename")))) .AppendStage(new BsonDocument("$sort", new BsonDocument { {"metadata .type", 1}, {"lowercaseFileName", 1} })).ToListAsync();
    • 另外,不用加$hint,mongo很聪明,可以使用正确的索引。
    • 是的,我同意这一点,mongodb 足够聪明,可以使用正确的索引
    【解决方案2】:

    您是否尝试设置 Collat​​ionStrenght = 2?

    您的代码与您的代码类似,您只需在 FindObject 中设置排序规则:

     var options = new FindOptions
        {
            Modifiers = new BsonDocument("$hint", "PathTypeFilenameIndex"),
            Collation = new Collation("en", strength: CollationStrength.Secondary)
        };
    

    【讨论】:

      猜你喜欢
      • 2019-01-31
      • 1970-01-01
      • 2014-04-20
      • 2014-05-20
      • 2020-06-11
      • 2018-03-09
      • 2016-10-22
      • 2013-10-14
      • 2013-04-17
      相关资源
      最近更新 更多