首页 > 解决方案 > MongoDB C# 不区分大小写的排序和索引

问题描述

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

        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();

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

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

a, Ab, B, c, D

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

Ab, B, D, a, c

这是因为 MongoDB 使用简单的二进制比较对数据进行排序,其中 'A' < 'a' 因为它们的 ASCII 代码。

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

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

标签: c#mongodbsortingindexing

解决方案


我认为您可以将聚合管道与$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();

推荐阅读