map型字段 mongodb_mapreduce-通过关键字段查找MongoDB集合中的所有重复文档

这里接受的最高答案是这样的:

uniqueIds: { $addToSet: "$_id" },

这也将为您返回一个名为id的新字段,其中包含ID列表。 但是,如果您只想要该字段及其数量怎么办? 然后就是这样:

db.collection.aggregate([

{$group: { _id: {name: "$name"},

count: {$sum: 1} } },

{$match: { count: {"$gt": 1} } }

]);

为了说明这一点,如果您来自MySQL和PostgreSQL之类的SQL数据库,则习惯于聚合函数(例如COUNT(),SUM(),MIN(),MAX()),这些函数与GROUP BY语句一起使用,可用于 例如,查找表中列值出现的总数。

SELECT COUNT(*), my_type FROM table GROUP BY my_type;

+----------+-----------------+

| COUNT(*) | my_type |

+----------+-----------------+

| 3 | Contact |

| 1 | Practice |

| 1 | Prospect |

| 1 | Task |

+----------+-----------------+

如您所见,我们的输出显示每个my_type值出现的计数。 要在MongoDB中查找重复项,我们将以类似的方式解决该问题。 MongoDB具有聚合操作,可以将多个文档中的值分组在一起,并且可以对分组的数据执行各种操作以返回单个结果。 这是在SQL中聚合函数的类似概念。

假设有一个名为contacts的集合,初始设置如下所示:

db.contacts.aggregate([ ... ]);

此聚合函数采用一组聚合运算符,在我们的示例中,我们希望使用$ group运算符,因为我们的目标是根据字段的计数(即字段值的出现次数)对数据进行分组。

db.contacts.aggregate([

{$group: {

_id: {name: "$name"}

}

}

]);

这种方法有点特质。 _id字段是使用分组依据运算符所必需的。 在这种情况下,我们将$ name字段分组。 _id中的键名可以有任何名称。 但是我们使用名称是因为这里很直观。

通过仅使用$ group运算符运行聚合,我们将获得所有名称字段的列表(无论它们在集合中出现一次还是多次):

db.contacts.aggregate([

{$group: {

_id: {name: "$name"}

}

}

]);

{ "_id" : { "name" : "John" } }

{ "_id" : { "name" : "Joan" } }

{ "_id" : { "name" : "Stephen" } }

{ "_id" : { "name" : "Rod" } }

{ "_id" : { "name" : "Albert" } }

{ "_id" : { "name" : "Amanda" } }

请注意上面的聚合方式。 它获取了带有名称字段的文档,并返回提取的名称字段的新集合。

但是我们想知道的是字段值会出现多少次。 $ group运算符采用一个计数字段,该字段使用$ sum运算符将表达式1添加到该组中每个文档的总数中。 因此$ group和$ sum一起返回给定字段(例如名称)产生的所有数值的总和。

db.contacts.aggregate([

{$group: {

_id: {name: "$name"},

count: {$sum: 1}

}

}

]);

{ "_id" : { "name" : "John" }, "count" : 1 }

{ "_id" : { "name" : "Joan" }, "count" : 3 }

{ "_id" : { "name" : "Stephen" }, "count" : 2 }

{ "_id" : { "name" : "Rod" }, "count" : 3 }

{ "_id" : { "name" : "Albert" }, "count" : 2 }

{ "_id" : { "name" : "Amanda" }, "count" : 1 }

由于目标是消除重复项,因此需要多执行一个步骤。 要仅获取计数大于一个的组,可以使用$ match运算符过滤结果。 在$ match运算符中,我们将告诉它查看count字段,并使用代表“大于”的$ gt运算符和数字1告诉它查找大于1的计数。

db.contacts.aggregate([

{$group: { _id: {name: "$name"},

count: {$sum: 1} } },

{$match: { count: {"$gt": 1} } }

]);

{ "_id" : { "name" : "Joan" }, "count" : 3 }

{ "_id" : { "name" : "Stephen" }, "count" : 2 }

{ "_id" : { "name" : "Rod" }, "count" : 3 }

{ "_id" : { "name" : "Albert" }, "count" : 2 }

附带说明一下,如果通过像Mongoid for Ruby这样的ORM使用MongoDB,则可能会出现以下错误:

The 'cursor' option is required, except for aggregate with the explain argument

这很可能意味着您的ORM已过时,并且正在执行MongoDB不再支持的操作。 因此,更新您的ORM或找到修复程序。 对于Mongoid,这是我的解决方法:

module Moped

class Collection

# Mongo 3.6 requires a `cursor` option be passed as part of aggregate queries. This overrides

# `Moped::Collection#aggregate` to include a cursor, which is not provided by Moped otherwise.

#

# Per the [MongoDB documentation](https://docs.mongodb.com/manual/reference/command/aggregate/):

#

# Changed in version 3.6: MongoDB 3.6 removes the use of `aggregate` command *without* the `cursor` option unless

# the command includes the `explain` option. Unless you include the `explain` option, you must specify the

# `cursor` option.

#

# To indicate a cursor with the default batch size, specify `cursor: {}`.

#

# To indicate a cursor with a non-default batch size, use `cursor: { batchSize: }`.

#

def aggregate(*pipeline)

# Ordering of keys apparently matters to Mongo -- `aggregate` has to come before `cursor` here.

extract_result(session.command(aggregate: name, pipeline: pipeline.flatten, cursor: {}))

end

private

def extract_result(response)

response.key?("cursor") ? response["cursor"]["firstBatch"] : response["result"]

end

end

end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为什么会这样[user_mongo@nosql01 replicaset]$ cd /opt [user_mongo@nosql01 opt]$ ll total 0 drwxr-xr-x. 3 root root 25 Mar 16 17:08 servers drwxr-xr-x. 2 root root 51 Mar 16 17:10 software [user_mongo@nosql01 opt]$ tar -zxvf /opt/software/mongodb-linux-x86_64-rhel70-4.4.12.tgz -C /opt/servers/mongodb_demo/replicaset/ mongodb-linux-x86_64-rhel70-4.4.12/LICENSE-Community.txt tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/LICENSE-Community.txt: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/MPL-2 tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/MPL-2: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/README tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/README: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/THIRD-PARTY-NOTICES tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/THIRD-PARTY-NOTICES: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/install_compass tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/install_compass: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/mongo tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/mongo: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/mongod tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/mongod: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/mongos tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/mongos: Cannot open: No such file or directory tar: Exiting with failure status due to previous errors [user_mongo@nosql01 opt]$ tar -zcvf /opt/software/mongodb-linux-x86_64-rhel70-4.4.12.tgz -C /opt/servers/mongodb_demo/replicaset/ tar: Cowardly refusing to create an empty archive Try `tar --help' or `tar --usage' for more information.
最新发布
06-01

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值