Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.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
Node.js 返回重复结果的Mongoose查询_Node.js_Mongodb_Mongoose_Mongodb Query_Aggregation Framework - Fatal编程技术网

Node.js 返回重复结果的Mongoose查询

Node.js 返回重复结果的Mongoose查询,node.js,mongodb,mongoose,mongodb-query,aggregation-framework,Node.js,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,查询接收一对坐标、最大距离半径、一个“跳过”整数和一个“限制”整数。函数应根据给定的位置返回最近和最新的位置。代码中没有可见的错误,但是,当我再次调用查询时,它会返回重复的结果。根据返回的结果更新“skip”变量 例如: 1) 我用skip=0,limit=10进行查询。我收到10个非重复位置 2) 现在再次调用Query,skip=10,limit=10。我从第一次查询中收到另外10个位置的重复结果 质疑 模式 var locationSchema = new Schema({

查询接收一对坐标、最大距离半径、一个“跳过”整数和一个“限制”整数。函数应根据给定的位置返回最近和最新的位置。代码中没有可见的错误,但是,当我再次调用查询时,它会返回重复的结果。根据返回的结果更新“skip”变量

例如:

1) 我用skip=0,limit=10进行查询。我收到10个非重复位置

2) 现在再次调用Query,skip=10,limit=10。我从第一次查询中收到另外10个位置的重复结果

质疑

模式

var locationSchema = new Schema({
        date_created: { type: Date },
        coordinates: [],
        text: { type: String }
});

我试着到处寻找解决办法。我唯一的选择是Mongo的版本?我使用Mongoose4.x.x,mongodb类似于2.5.6。我相信。有什么想法吗 第二种情况是,“跳过”和“限制”样式的分页对大数据集的表单性能非常糟糕,应该尽量避免。因此,最好根据数据出现的“范围”来选择数据,而不是“跳过”之前显示的所有结果

这里要做的第一件事是使用一个命令,该命令可以将距离与其他信息一起“投影”到文档中。的aggregation命令对此很有用,尤其是因为我们希望进行其他排序:

var seenIds = [],
    lastDistance = null,
    lastDate = null;

Locations.aggregate(
    [
        { "$geoNear": {
            "near": [x,y],
            "maxDistance": maxDistance
            "distanceField": "dist",
            "limit": 10
        }},
        { "$sort": { "dist": 1, "date_created": -1 }
    ],
    function(err,results) {
        results.forEach(function(result) {

            if ( ( result.dist != lastDistance ) || ( result.date_created != lastDate ) ) {
                seenIds = [];
                lastDistance = result.dist;
                lastDate = result.date_created;
           }
           seenIds.push(result._id);
       });
       // save those variables to session or other persistence
       // do something with results
    }
)
这是您的结果的第一次迭代,您将在其中获取前10个。注意循环中的逻辑,其中检查结果中的每个文档是否存在“date_created”或文档中当前存在的投影“dist”字段的更改,如果出现这种情况,“seenIds”数组将从所有当前条目中删除。一般的做法是在每次迭代中测试并可能更新所有变量,如果没有变化,则将项目添加到“seenid”列表中

所有这三个正在处理的变量都需要存储在某个地方,等待下一个请求。对于web应用程序,会话存储是理想的,但不同的方法有所不同。您只希望在我们启动下一个请求时调用这些值,因为在下一次和后续迭代中,我们稍微更改了查询:

Locations.aggregate(
    [
        { "$geoNear": {
            "near": [x,y],
            "maxDistance": maxDistance,
            "minDistance": lastDistance,
            "distanceField": "dist",
            "limit": 10,
            "query": {
                "_id": { "$nin": seenIds },
                "date_created": { "$lt": lastDate }
            }
        }},
        { "$sort": { "dist": 1, "date_created": -1 }
    ],
    function(err,results) {
        results.forEach(function(result) {
            if ( ( result.dist != lastDistance ) || ( result.date_created != lastDate ) ) {
                seenIds = [];
                lastDistance = result.dist;
                lastDate = result.date_created;
           }
           seenIds.push(result._id);
       });
       // save those variables to session or other persistence
       // do something with results
    }
)
因此,输入“MindDistance”参数是为了排除已经看到的任何“更接近”的结果,并在查询中放置额外的检查,“date_created”需要“小于”记录的“lastDistance”,因为我们是按降序排序的,最后是“sure”筛选排除列表中记录的任何“_id”值,因为这些值没有更改

现在,对于地理空间数据,“seenIds”列表不太可能增长,因为通常情况下,您不会在相同的距离上找到所有东西,但这是一个分页排序数据列表的一般过程,因此值得理解这一概念

因此,如果您希望能够使用辅助字段对地理空间数据进行排序,并同时考虑“近”距离,那么这是一种通用方法,通过将距离值投影到文档结果中,以及在任何不会使其唯一的更改之前存储最后看到的值


一般的概念是“推进最小距离”,以使每页结果逐渐“远离”查询中使用的源起点。

在执行
$near
后,您按创建的
日期对结果进行排序,这不是一个好主意,也可能不是您想要的,因为它“扔掉了”由于近操作而返回的“排序”。在可能的情况下,也应避免使用“跳过”和“限制”分页方法,并且仅在“需要”编号分页以“跳转”到且没有其他方法的情况下使用。我认为它的目的至少是找到“最近的”东西,然后按照创造的顺序在大约相同的距离对任何东西进行排序?没错!我能做什么?传呼怎么样?你真的需要页码吗?或者你可以简单地要求下一页和下一页等等。这正是我的意思,获取一页,然后获取“下一页”等等,每次需要一个新页时,例如,你从不“跳到第5页”。我这样问是因为这避免了跳跃和限制,因此有更好的方法。
Locations.aggregate(
    [
        { "$geoNear": {
            "near": [x,y],
            "maxDistance": maxDistance,
            "minDistance": lastDistance,
            "distanceField": "dist",
            "limit": 10,
            "query": {
                "_id": { "$nin": seenIds },
                "date_created": { "$lt": lastDate }
            }
        }},
        { "$sort": { "dist": 1, "date_created": -1 }
    ],
    function(err,results) {
        results.forEach(function(result) {
            if ( ( result.dist != lastDistance ) || ( result.date_created != lastDate ) ) {
                seenIds = [];
                lastDistance = result.dist;
                lastDate = result.date_created;
           }
           seenIds.push(result._id);
       });
       // save those variables to session or other persistence
       // do something with results
    }
)