如何 return 区分 mongodb 中的 $or?

How to return distinct $or in mongodb?

所以我有这个查询

db.collection.find($or:[{data_id:123},{data_id:345},{data_id:443}]);

如何将其调整为 return $or 的每个部分中的一个。 I.E 类似于 SQL:

SELECT DISTINCT data_id, [...] WHERE data_id='123' OR data_id='345'... 

而不是 $or 使用 $in 查询,这将满足您的目的。

db.collection.find({data_id:{$in: [123, 345, 443]}});

您的问题需要考虑您拥有的文件,因为 "distinct" 在这里可能意味着一些不同的事情。考虑以下示例:

{
    "tripId": 123,
    "thisField": "this",
    "thatField": "that"
},
{
    "tripId": 123,
    "thisField": "other",
    "thatField": "then"
},
{
    "tripId": 345,
    "thisField": "other",
    "thatField": "then"
},
{
    "tripId": 345,
    "thisField": "this",
    "thatField": "that"
},
{
    "tripId": 123,
    "thisField": "this",
    "thatField": "that"
},
{
    "tripId": 789,
    "thisField": "this",
    "thatField": "that"
}

MongoDB 有 .distinct() 方法,该方法会 return 单个字段的不同值,但只有一个字段和项目被简单地 returned作为这些字段值的数组。

对于您想要的任何其他内容,.aggregate() 方法。这是聚合管道,它执行许多不同的功能,并且由于其处理的 "pipeline" 性质,可以处理一些非常复杂的操作。

特别是在这里,您可能希望使用 $group 管道阶段,以便 "group" 基于键将值组合在一起。 "key" 在 $group 语句中以 _id 键的形式表示。很像 SQL 中的 "SELECT" 带有 "GROUP BY" 或 "DISTINCT" 修饰符(它们在功能上大致相同),您需要在结果中指定您想要的所有字段.

此外,任何未在语句的 "GROUP BY" 部分中指定的内容都必须服从某种 "grouping operation" 以便 select 哪些字段值当前的。为此,有多种 "Group Accumulator Operators" 可以对这些值起作用:

在这种情况下使用 $first 运算符的示例:

db.collection.aggregate([
    { "$match": {
        "tripId": { "$in": [ 123,345 ] }
    }},
    { "$group": {
        "_id": "$tripId",
        "thisField": { "$first": "$thisField" },
        "thatField": { "$first": "$thatField" },
        "total": { "$sum": 1 }
    }}
])

给出这个结果:

{ "_id" : 345, "thisField" : "other", "thatField" : "then", "total" : 2 }
{ "_id" : 123, "thisField" : "this", "thatField" : "that", "total" : 3 }

因此,通过添加 $sum 运算符来计算相同不同值的出现次数,这将拾取累加器表达式中提到的指定字段中值的 "first" 出现次数在分组键之外。

在 MongoDB 2.6 版本中,您可以 "shortcut" 使用 $$ROOT 表达式变量单独命名您想要的所有字段。这是对文档中存在的 "all" 字段的引用,截至当前阶段使用它的状态。写起来稍微短了点,但是由于语法的原因输出有点不同:

db.collection.aggregate([
    { "$match": {
        "tripId": { "$in": [ 123,345 ] }
    }},
    { "$group": {
        "_id": "$tripId",
        "doc": { "$first": "$$ROOT" },
        "total": { "$sum": 1 }
    }}
])

输出为:

{
    "_id" : 345,
    "doc" : {
            "_id" : ObjectId("54feaf3839c29b9cd470bcbe"),
            "tripId" : 345,
            "thisField" : "other",
            "thatField" : "then"
    },
    "total" : 2
}
{
    "_id" : 123,
    "doc" : {
            "_id" : ObjectId("54feaf3839c29b9cd470bcbc"),
            "tripId" : 123,
            "thisField" : "this",
            "thatField" : "that"
    },
    "total" : 3
}

这是大多数 $group 聚合操作的一般情况,您指定 "key" 并将其他字段呈现给某种 "grouping operator"/"accumulator"。

另一种情况是,如果您要查找 "all" 字段的 "distinct" 次出现,那么您可以将这些表示为组表达式的 "key" 的一部分,如下所示:

db.collection.aggregate([
    { "$match": {
        "tripId": { "$in": [ 123,345 ] }
    }},
    { "$group": {
        "_id": {
            "tripId": "$tripId",
            "thisField": "$thisField",
            "thatField": "$thatField"
        },
        "total": { "$sum": 1 }
    }}
])

这给了我们这个输出:

{
    "_id" : {
            "tripId" : 345,
            "thisField" : "this",
            "thatField" : "that"
    },
    "total" : 1
}
{
    "_id" : {
            "tripId" : 345,
            "thisField" : "other",
            "thatField" : "then"
    },
    "total" : 1
}
{
    "_id" : {
            "tripId" : 123,
            "thisField" : "other",
            "thatField" : "then"
    },
    "total" : 1
}
{
    "_id" : {
            "tripId" : 123,
            "thisField" : "this",
            "thatField" : "that"
    },
    "total" : 2
}

总结果是 4 个文档,其中考虑了作为 "composite key" 的一部分提到的每个字段的 "distinct" 值。它正确地说明了大多数这些组合出现了 1 次,但有一个示例实际出现了两次且所有值都相同。

自然地,$$ROOT 变量不适用于此处,因为 "whole document" 包含每个文档的 "unique" _id 字段。您始终可以预先添加 $project 阶段以过滤掉该字段,但指定所需字段的相同条件适用:

db.collection.aggregate([
    { "$match": {
        "tripId": { "$in": [ 123,345 ] }
    }},
    { "$project": {
        "_id": 0,
        "tripId": 1,
        "thisField": 1,
        "thatField": 1
    }},
    { "$group": {
        "_id": "$$ROOT",
        "total": { "$sum": 1 }
    }}
])

因此,这是一个介绍,其中包含您可以使用 MongoDB 以 "distinct" 查询的形式执行的操作的示例,特别是聚合框架。文档中还提供了各种其他常见的 SQL to Aggregation mapping 示例。

另一个一般情况是您使用 $or in your question. As you see in the samples here, when you want the same "or" condition over values of the same field, then the more efficient way to write this in your query is with the $in 运算符。这不是 "query documents" 的数组,而是 "possible values" 的数组到它在表达式中检查的公共字段。它基本上是一个 $or 条件,但在这种情况下以较短的形式表示。