0

我需要对整个集合进行区分大小写和变音符号的排序,这是 mongoengine 无法做到的,因为 mongodb 只有区分大小写的排序。

所以我有一个想法如何做到这一点。获取集合中的所有条目,然后在 python 中执行我自己的 unicode 不区分大小写排序。但是由于我的收藏非常庞大,因此存在长时间延迟的问题。有没有办法,如何更快地做到这一点?

def initMongoengineData(model, criteria, only):
    if model == None:
        return

    print "-- starting DB query"
    print datetime.datetime.now()

    querySet = model.objects(**criteria).only(*only)

    print "-- data loaded"
    print datetime.datetime.now()

    return mongoengineQuerySetToList(querySet)

def mongoengineQuerySetToList(querySet):
    queryList = []
    dict = {}
    objDict = None
    objCounter = 0
    for obj in querySet:
        objCounter += 1
        dict = {}
        objDict = obj.to_mongo()
        for key in objDict:
            dict[key] = objDict[key]
        queryList.append(dict)

    print "-- structure for sorting is ready"
    print datetime.datetime.now()
    print "-- number of objects:"
    print objCounter
    queryList.sort(key=lambda x: x['surname'].lower())
    print "-- structure is sorted"
    print datetime.datetime.now()

    return queryList


model = Players  # mongoengine Document
criteria = {} 
only = ['surname']
datalist = initMongoengineData(model, criteria, only)

输出:

-- starting DB query
2013-08-24 16:45:57.721000
-- data loaded
2013-08-24 16:45:57.721000
-- structure for sorting is ready
2013-08-24 16:46:52.257000
-- number of objects:
82668
-- structure is sorted
2013-08-24 16:46:52.493000

之后的数据加载和排序非常快,但准备排序结构大约需要1 分钟,这是很长的延迟。任何人都可以帮助如何通过收集如此多的条目更快地做到这一点?

4

1 回答 1

1

您只需要按一个字段排序(surname在本例中)。

因此,使用 mongoengine 进行基本排序(排序)model.objects(**criteria).only(*only).order_by('+surname')请参见http://docs.mongoengine.org/en/latest/guide/defining-documents.html#ordering

但是,如果您真的需要不区分大小写的排序,则没有简单的方法。

在您的代码中,最慢的块是for obj in querySet. 在此块中,您从查询集中获取项目。您可以尝试使用for obj in list(querySet)一次获取所有数据,但我不相信它真的会提高性能。

最好的方法是添加小写的附加字段。您也可以为此尝试 map reduce。我找不到如何使用 agregation 来做到这一点project

此外,不区分大小写的索引将在 mongo 2.5.w(可能是 11 月底)上参见https://jira.mongodb.org/browse/SERVER-90

于 2013-08-25T06:01:32.000 回答