簡體   English   中英

沒有影子列的MongoDB是否有更好的區分大小寫的排序方式?

[英]Is there a better way of doing case insensitive sort in MongoDB without shadow columns?

我有幾個對象需要執行不區分大小寫的排序。 有人告訴我我不能在數據庫中添加陰影列以規范化值。 因此,我正在使用聚合對輸出進行排序。

我有一個這樣表示的簡單對象:

_id:ObjectID

createdOn:創建時間對象

lastUpdatedOn:時間對象上次更新

名稱:對象的名稱

isActive:布爾值,表示對象當前是否處於活動狀態

這是我的聚合函數:

db.organization.aggregate(
    [
        {
            $match: { isActive: true }
        },
        {
            $project: {
                      lastUpdatedOn: 1,
                      createdOn: 1,
                      name: 1,
                      normalizedName: {$toLower: "$name"}
                      }
        },
        {
            $sort: { normalizedName: 1 }
        },
        {
            $project: {
                      lastUpdatedOn: 1,
                      createdOn: 1,
                      name: 1
                      }
        }
    ]
)

它首先確保我們僅處理活動對象,為我們的排序創建歸一化字段,執行排序,然后刪除歸一化字段,以使它不會暴露給用戶。 它可以工作,並根據名稱字段將所有對象按字母順序排列,但是我不知道是否有更好的方法。

不一定有很大的改進,但是根據您的特定用例,將$$ROOT投影為捕獲與臨時排序列分開的原始文檔可能會更干凈:

db.organization.aggregate(
    [
        {
            $match: { isActive: true }
        },
        {
            $project: {
                      doc: '$$ROOT'
                      normalizedName: {$toLower: "$name"}
                      }
        },
        {
            $sort: { normalizedName: 1 }
        },
        {
            $project: { doc: 1 }
        }
    ]
)

不利的一面是您最終將原始文檔放在doc屬性中,但是可以通過Array#map類的內容輕松清除客戶端。 或者,您可以修改最終的$project來將每個字段提升為頂層,但這可能很乏味。

盡管MondoDB不提供它,但是您可以很容易地用PHP或任何其他語言來實現。 這是在PHP中的操作方法。

$cn = new MongoClient($dbHost);
$db = $cn->selectDB($dbName);
$col = new MongoCollection($db, $collectionName);

$cursor = $col->find();
$cursor = iterator_to_array($cursor);

foreach ($cursor as $key => $row) {
    $name[$key] = $row['name'];
    $email[$key] = $row['email'];
}
//$name is the field to sort on, taken from the above loop
//You can use SORT_ASC or SORT_DESC

array_multisort($name, SORT_ASC, $cursor);

foreach ($cursor as $doc) {
    echo $doc['name'].'-'.$doc['email'].'<br/>';
}

我意識到這是一個古老的問題,但是由於支持Mongo 3.4 排序規則 ,因此這變得容易得多。 對於帶有歸類的聚合,只需添加一個歸類對象,如下所示: db.organization.aggregate([pipelineobjs],{collation: {locale:'en_US'}})

我相信您的特定匯總應如下所示:

db.organization.aggregate(
    [
        {
            $match: { isActive: true }
        },
        {
            $project: {
                      lastUpdatedOn: 1,
                      createdOn: 1,
                      name: 1
                      }
        },
        {
            $sort: { name: 1 }
        },
        {
            $project: {
                      lastUpdatedOn: 1,
                      createdOn: 1,
                      name: 1
                      }
        }
    ],
    {collation: {locale:'en_US'}}
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM