在Mongodb/pymongo中按字符串长度排序

7

我想知道是否有人知道如何按字符串长度对mongodb的find()结果进行排序。

我尝试了类似于db.foo.find().sort({item.lenght:-1})的操作,但显然不起作用。有人能帮帮我,并提供一种在pymongo中完成相同操作的方法吗?


1
据我所知,MongoDB不支持对字符串长度进行操作。例如,您不能查询字符串长度小于或大于某个值的情况。通常我会编写一个JS脚本来完成这个任务。 - Sikorski
1
聚合函数怎么样? - dikesh
@Dikesh,我真的希望这是可能的,但目前还不行。请看答案。 - Neil Lunn
3个回答

7

有许多我个人希望在聚合框架中看到的东西(和基本API),例如:

数学函数

  • log(如对数)
  • ceil
  • floor

数组

  • sum

字符串

  • length

仅举几例。

而这还没有使用“$mod”运算符或其他情况下的不常见用法,如“ceil”和“floor”。但我跑题了。

你的“字符串长度”属于此类。提出一个JIRA问题。但现在,您可以使用mapReduce和现有的JavaScript功能:

db.collection.mapReduce(
    function() {
        emit( this.item.length, this.item );
    },
    function(key,values) {
        return values;
    },
    { "out": { "inline": 1 } }
)

因此,虽然这确实具有"mapReduce"的奇妙风格,返回了一个重新构造过的文档,并且当然在数组中匹配相同的长度,但它所做的是利用"mapReduce"的性质(不仅限于MongoDB),并允许在响应中对发射的"key"值进行排序。


6

现在,在MongoDB v3.4+中,使用聚合框架和$strLenBytes可以解决这个问题。给定以下文档:

{_id: 0, name: "Bob"}

我们可以使用。
db.mycollection.aggregate([{
    $project: {
         byteLength: {$strLenBytes: "$name"}
    }
}])

这将返回 3,表示字节数。


1
实际上应该是[{ "$addFields": { "len": { "$strLenBytes": "$name" } }},{ "$sort": { "len": 1 }},{ "$project": { "len": 0 }}]。为了完全复制OP所请求的操作,即返回“原样”但排序的文档。感谢提及。 - Neil Lunn
@NeilLunn 是的,我只专注于返回长度,而不是排序,因为我觉得排序很简单,如果你愿意,可以改变答案以涵盖两者。 - rrrr-o

1
不,实际上是不可能的。 我曾经遇到过类似的问题,我的解决方法是将每个对象的字符串长度存储为对象本身的属性。这样就绕开了这个问题。
如果你认为应该实现这个功能(我觉得应该),我建议你在JIRA上投票支持这个问题。不知为何,它的票数不多。

https://jira.mongodb.org/browse/SERVER-5319


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接