【问题标题】:Find with filter and map使用过滤器和地图查找
【发布时间】:2015-11-04 20:13:01
【问题描述】:

我在MongoDB中有如下语句:

db.getCollection('Forms').find({"Id": { $nin: db.Forms.find({"Status": "DELETE" }, {_id:0, Id:1}).map(function (fr) { return fr.Id;} ) }})

Forms 集合是一个只能追加的集合,可以写入 ADD、UPDATE 和 DELETE 状态记录,这个“选择”的作用是返回集合中没有 DELETE 记录的所有表单。

问题是:如何使用 MongoDB 驱动程序编写过滤器?我尝试了以下方法,它返回一个空列表:

new BsonDocument("Id", "{ $nin: db.Forms.find({\"Status\": \"DELETE\" }, {_id:0, Id:1}).map(function (fr) { return fr.Id;} ) }");

以下是集合中一些行的示例,我已经排除了大部分字段,只是在这里选择了相关字段:

/* 1 */{"_id" : ObjectId("55caeb15b33c2d1ff84a618c"),"Id" : "55cae279b33c2d0c2831340c","Status" : "DELETE"}
/* 2 */{"_id" : ObjectId("55cae279b33c2d0c2831340c"),"Id" : "55cae279b33c2d0c2831340c","Status" : "ADD"}
/* 3 */{"_id" : ObjectId("55cae263b33c2d0c2831340b"),"Id" : "55cae21eb33c2d1c187fb2b8","Status" : "DELETE"}
/* 4 */{"_id" : ObjectId("55cae21eb33c2d1c187fb2b8"),"Id" : "55cae21eb33c2d1c187fb2b8","Status" : "ADD"}
/* 5 */{"_id" : ObjectId("55cae200b33c2d1c187fb2b6"),"Id" : "55cae177b33c2d1c187fb2b1","Status" : "DELETE"}
/* 6 */{"_id" : ObjectId("55cae192b33c2d1c187fb2b2"),"Id" : "55cae177b33c2d1c187fb2b1","Status" : "UPDATE"}
/* 7 */{"_id" : ObjectId("55cae177b33c2d1c187fb2b1"),"Id" : "55cae177b33c2d1c187fb2b1","Status" : "ADD"}
/* 8 */{"_id" : ObjectId("55cad0bcb33c2d1040d49d25"),"Id" : "55c9ec2bb33c2d2d04126cf7","Status" : "DELETE"}
/* 9 */{"_id" : ObjectId("55c9f5f0b33c2c27947ef05b"),"Id" : "55c9ec2bb33c2d2d04126cf7","Status" : "UPDATE"}
/* 10 */{"_id" : ObjectId("55c9f5c5b33c2c27947ef05a"),"Id" : "55c9ec2bb33c2d2d04126cf7","Status" : "UPDATE"}
/* 19 */{"_id" : ObjectId("55c9ec2bb33c2d2d04126cf7"),"Id" : "55c9ec2bb33c2d2d04126cf7","Status" : "ADD"}
...
/* 44 */{"_id" : ObjectId("55c32785b33c2c206014caf0"),"Id" : "55c08ea1b33c2d24f0aaf697","Status" : "UPDATE"}
/* 45 */{"_id" : ObjectId("55c31762b33c2c235cbef0f9"),"Id" : "55c08ea1b33c2d24f0aaf697","Status" : "UPDATE"}
/* 46 */{"_id" : ObjectId("55c31304b33c2c235cbef0e9"),"Id" : "55c08ea1b33c2d24f0aaf697","Status" : "UPDATE"}
/* 47 */{"_id" : ObjectId("55c2071fb33c2d0d1ca701fe"),"Id" : "55c08ea1b33c2d24f0aaf697","Status" : "UPDATE"}
/* 48 */{"_id" : ObjectId("55c1ee9db33c2d2090685c29"),"Id" : "55c08ea1b33c2d24f0aaf697","Status" : "UPDATE"}
/* 49 */{"_id" : ObjectId("55c1e267b33c2d2090685bff"),"Id" : "55c08ea1b33c2d24f0aaf697","Status" : "UPDATE"}
/* 50 */{"_id" : ObjectId("55c1b2eeb33c2c1f0cb151c2"),"Id" : "55c08ea1b33c2d24f0aaf697","Status" : "UPDATE"}

因此,选择需要排除所有具有“DELETE”条目的表单(而不是行) - 即,一旦表单有 DELETE 记录,就必须将其从列表中排除。

澄清一下:_id 字段是每行的唯一 ID,而 Id 是我在选择中使用的表单的 ID。

编辑:虽然@BlakesSeven 建议的重复答案向我解释了我不能像我试图做的那样调用函数“内联”,但问题仍然存在:如何将这行代码编写为MapReduce使用 MongoDB C# 驱动程序

db.getCollection('Forms').find({"Id": { $nin: db.Forms.find({"Status": "DELETE" }, {_id:0, Id:1}).map(function (fr) { return fr.Id;} ) }})

【问题讨论】:

  • 您能解释一下为什么您的建议“显然”不起作用吗?
  • @CodeCaster:抱歉,这有点不清楚:它只返回一个空列表,即过滤器没有返回任何内容。我将编辑问题以使其更清楚。
  • 您的状态字段是数组吗?是否有理由先选择 Id 并按它们过滤而不是立即按状态过滤?
  • @FireAlkazar:不,每个表单可以有多个不同状态的行——所以同一个表单可以有五个具有相同ID的行,但是状态不同,即添加时的第一个,然后对其进行更新,最后删除(如果相关)。一旦插入了 DELETE 行,我想从列表中排除该表单。我希望这是有道理的?我将整理一个列表以快速显示数据。
  • 当您的问题被“赞成”时,您必须理解我的立场,因为这实际上只是您和他人对流程的“误解”。所以不要生气,即使它是“愤怒”的一部分,为什么人们仍然不明白这一点。因此,我建议“重新阅读”那里给出的答案,直到它沉入其中。您所看到的是外壳是一个查询操作(如外壳允许)的“结果”,就像一个变量一样被“转置”到表单中当它作为另一个语句中的参数使用时。他们嵌入。就是这么说的。

标签: c# mongodb filter


【解决方案1】:

Mongo shell 是一个非常先进的 MongoDB 客户端。
在这种情况下,它会为您执行 2 个查询,而不是一个。
作为证明,您可以探索执行计划,它们将是相等的(查询的格式是为了便于阅读):

db.getCollection('Forms')
    .find({"Id": { $nin: db.Forms.find({"Status": "DELETE" }, {_id:0, Id:1}).map(function (fr) { return fr.Id;} )}})
    .explain()

还有

var excludedIds = db.Forms.find({"Status": "DELETE" }, {_id:0, Id:1}).map(function (fr) { return fr.Id;} )
db.getCollection('Forms')
    .find({"Id": { $nin: excludedIds }})
    .explain()

所以你需要在你的客户端做同样的事情:首先查询excludedIds,然后基于excludedIds创建一个过滤器并再次查询Forms集合。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多