Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 聚合框架中的$skip和$limit_Mongodb_Aggregation Framework - Fatal编程技术网

Mongodb 聚合框架中的$skip和$limit

Mongodb 聚合框架中的$skip和$limit,mongodb,aggregation-framework,Mongodb,Aggregation Framework,当我阅读该文件时,我发现以下注释: 当$sort紧跟在管道中的$limit之前时,$sort操作只会在执行过程中维护前n个结果,其中n是指定的限制,MongoDB只需要在内存中存储n个项。当allowDiskUse为true且n项超过聚合内存限制时,此优化仍然适用 如果我对这一点是正确的,那么它只适用于同时使用$sort和$limit的情况,如 db.coll.aggregate([ ..., {$sort: ...}, {$limit: limit}, ...

当我阅读该文件时,我发现以下注释:

当$sort紧跟在管道中的$limit之前时,$sort操作只会在执行过程中维护前n个结果,其中n是指定的限制,MongoDB只需要在内存中存储n个项。当allowDiskUse为true且n项超过聚合内存限制时,此优化仍然适用

如果我对这一点是正确的,那么它只适用于同时使用$sort和$limit的情况,如

db.coll.aggregate([
    ...,
    {$sort: ...},
    {$limit: limit},
    ...
]);
然而,我想大多数时候我们会

db.coll.aggregate([
    ...,
    {$sort: ...},
    {$skip: skip},
    {$limit: limit},
    ...
]);
问题1:如果我在此处使用$skip,是否意味着上述规则不适用

我问这个问题是因为理论上MongoDB仍然可以计算topn记录,并通过只排序topn记录来提高性能。但是我没有找到任何关于这个的文件。如果规则不适用

问题2:我是否需要将查询更改为以下内容以提高性能

db.coll.aggregate([
    ...,
    {$sort: ...},
    {$limit: skip + limit},
    {$skip: skip},
    {$limit: limit},
    ...
]);
编辑:我认为解释我的用例会使上述问题更有意义。我正在使用MongoDB 2.6提供的文本搜索功能查找产品。我担心如果用户输入一个非常常见的关键字,比如“red”,那么返回的结果会太多。因此,我正在寻找更好的方法来产生这个结果

EDIT2:上面的最后一个代码等于

db.coll.aggregate([
    ...,
    {$sort: ...},
    {$limit: skip + limit},
    {$skip: skip},
    ...
]);

因此,我们可以始终使用此表单应用top n规则。

由于这是我们正在讨论的文本搜索查询,因此最理想的表单如下:

db.collection.aggregate([
{ 
“$match”:{
“$text”:{“$search”:“蛋糕茶”}
}
},
{“$sort”:{“score”:{“$meta”:“textScore”}},
{“$limit”:跳过+限制},
{“$skip”:skip}
])
顶部“排序”结果中的内存保留的基本原理只能在其自身的“限制”范围内工作,这对于超出几个合理的数据“页面”的任何内容都不是最佳的

除了合理的内存消耗之外,额外的阶段可能会产生负面影响,而不是正面影响


这些实际上是MongoDB在当前形式下可用的文本搜索功能的实际限制。但是,对于任何更详细和需要更高性能的内容,就像许多SQL“全文”解决方案一样,最好使用外部“专门构建”的文本搜索解决方案。

我发现
限制
跳过
的顺序似乎无关紧要。如果我在
limit
之前指定
skip
,mongoDB将在
skip
之前在引擎盖下设置
limit

>db.system.profile.find().limit(1).sort({ts:-1}).pretty()
{
“op”:“命令”,
“ns”:“archiprod.userinfos”,
“命令”:{
“聚合”:“用户信息”,
“管道”:[
{
“$sort”:{
“updatedAt”:-1
}
},
{
“$限额”:625
},
{
“$skip”:600
}
],
},
“钥匙”:625,
“docsExamined”:625,
“cursorExhausted”:正确,
“努米菲尔德”:4,
“未回复”:25,
“米利斯”:25,
“计划摘要”:“IXSCAN{updatedAt:-1}”,
/*省略了一些字段*/
}
如果我切换
$skip
$limit
,会发生什么?在
键检查
文档检查
方面,我得到了相同的结果

>db.system.profile.find().limit(1).sort({ts:-1}).pretty()
{
“op”:“命令”,
“ns”:“archiprod.userinfos”,
“命令”:{
“聚合”:“用户信息”,
“管道”:[
{
“$sort”:{
“updatedAt”:-1
}
},
{
“$skip”:600
},
{
“$限额”:25
}
],
},
“钥匙”:625,
“docsExamined”:625,
“cursorExhausted”:正确,
“努米菲尔德”:5,
“未回复”:25,
“米利斯”:71岁,
“计划摘要”:“IXSCAN{updatedAt:-1}”,
}
然后我检查了查询的解释结果。我发现
totalDocsExamined
已经
625
处于
limit
阶段

> db.userinfos.explain('executionStats').aggregate([ { "$sort" : { "updatedAt" : -1 } }, { "$limit" : 625 }, { "$skip" : 600 } ])
{
    "stages" : [
        {
            "$cursor" : {
                "sort" : {
                    "updatedAt" : -1
                },
                "limit" : NumberLong(625),
                "queryPlanner" : {
                    "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                "updatedAt" : -1
                            },
                            "indexName" : "updatedAt_-1",
                        }
                    },
                },
                "executionStats" : {
                    "executionSuccess" : true,
                    "nReturned" : 625,
                    "executionTimeMillis" : 22,
                    "totalKeysExamined" : 625,
                    "totalDocsExamined" : 625,
                    "executionStages" : {
                        "stage" : "FETCH",
                        "nReturned" : 625,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 625,
                        "advanced" : 625,
                        "docsExamined" : 625,
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "nReturned" : 625,
                            "works" : 625,
                            "advanced" : 625,
                            "keyPattern" : {
                                "updatedAt" : -1
                            },
                            "indexName" : "updatedAt_-1",
                            "keysExamined" : 625,
                        }
                    }
                }
            }
        },
        {
            "$skip" : NumberLong(600)
        }
    ]
}
令人惊讶的是,我发现切换
$skip
$limit
会得到相同的
explain
结果

> db.userinfos.explain('executionStats').aggregate([ { "$sort" : { "updatedAt" : -1 } }, { "$skip" : 600 }, { "$limit" : 25 } ])
{
    "stages" : [
        {
            "$cursor" : {
                "sort" : {
                    "updatedAt" : -1
                },
                "limit" : NumberLong(625),
                "queryPlanner" : {
                    /* Omitted */
                },
                "executionStats" : {
                    "executionSuccess" : true,
                    "nReturned" : 625,
                    "executionTimeMillis" : 31,
                    "totalKeysExamined" : 625,
                    "totalDocsExamined" : 625,
                    /* Omitted */
                }
            }
        },
        {
            "$skip" : NumberLong(600)
        }
    ]
}

如您所见,尽管我在
$limit
之前指定了
$skip
,但在
解释
结果中,它仍然是
$limit
之前的
$skip

您在当前表单中所说的。您知道吗,是否正在进行增强MongoDB文本搜索的工作?关于将Solr与MongoDB结合使用,这里有一些很好的评论,@JohnBarça您寻求的答案实际上更“正式”,并且在性质上有点负载。无可否认,IMO MongoDB并没有试图成为一个“最优”的键/值存储,也没有像“数据库”那样尝试实现传统关系系统的所有功能。这一点的延伸是,通用“数据库”通常不会“进入”诸如“文本搜索”等专门领域。但这是一种观点,观点往往会发生变化。无论如何,用最有效的方法。我一直涉猎Mongo,非常喜欢某些功能。但我听到你在说什么。我是一个GIS爱好者,我喜欢已经完成的geojson功能和聚合空间增强功能,但就功能而言,离离开Postgres/Postgis还有很长的路要走。不过,我承认这是一个非常利基的领域。@JohnBarç;a我同意你们的看法。这只是一个临时解决方案,我可以用它快速和简单。我们确实想过集成一个搜索引擎。但直到