我正在使用java连接到MongoDB。 我想获取并计算两个字段的不同值,即requestId和telNum。我用谷歌搜索,但没有找到如何获取两个字段的不同值。
答案 0 :(得分:7)
MongoDB有一个Aggregation Framework和一个类似于SQL“GROUP BY”的管道,但这些阶段可以做更高级的工作。我们将展示一个三阶段示例,以获得不止一次出现的不同组合的计数。
考虑到你的意思是在文档中将requestId和telNum的相同值出现在一起,并将其视为相应的SQL
SELECT requestId, telNum, count(*) as counter
from collection
GROUP BY requestId, telNum
mongo shell位是从两个值组合的_id键上的组。因此:
db.collection.aggregate([
{$group: { _id: { requestId: "$requestId", telNum: "$telNum" }, count: {$sum: 1} } }
])
所以Java中的要点:
// Construct our _id to group on
DBObject fields = new BasicDBObject( "requestId", "$requestId" );
fields.put( "telNum", "$telNum" );
// Contruct group element
DBObject groupFields = new BasicDBObject( "_id", fields );
groupFields.put( "count", new BasicDBObject( "$sum", 1 ) );
DBObject group = new BasicDBObject( "$group", groupFields );
// Run aggregation
AggregationOutput output = collection.aggregate( group );
因此这里的输出将匹配上面的SQL。
进一步考虑,让我们考虑完整的SQL给我们不止一次的不同计数:
SELECT count(*)
FROM (
SELECT requestId, telNum, count(*) as counter
FROM collection
GROUP BY requestId, telNum
) a
WHERE a.counter > 1
因此我们可以更改代码,将聚合管道中的更多阶段再次添加到 $ match (WHERE / HAVING)和 $ group (GROUP BY):
// Construct a match on things with a count of more than 1
DBObject greaterThan = new BasicDBObject( "$gt", 1 );
DBObject matchFields = new BasicDBObject( "count", greaterTen );
DBObject match = new BasicDBObject( "$match", matchFields );
// Count the documents that match
DBObject newGroupFields = new BasicDBObject( "_id", null );
newGroupFields.put( "count", new BasicDBOject( "$sum", 1 ) );
DBObject group2 = new BasicDBObject( "$group", newGroupFields );
// Run aggregation
AggregationOutput output = collection.aggregate( group, match, group2 );
所以这链在链中的三个阶段
聚合允许您将这样的各个阶段“链接”在一起以获得结果。它非常适合这类工作,值得注意的是它比使用Map-Reduce要快得多,即使它仍然有它的用途。
根据需要编辑和播放。
还有一个有用的示例可以关注here
答案 1 :(得分:0)
import com.mongodb.MongoClient;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import com.mongodb.ServerAddress;
import java.util.Arrays;
// To directly connect to a single MongoDB server (note that this will not auto-discover the primary even
// if it's a member of a replica set:
MongoClient mongoClient = new MongoClient();
DB db = mongoClient.getDB( "mydb" );
AggregationOutput output =db.CollectionName.mapReduce(
function(){ emit(this.id, this.name);},
function(key, value) { return Array.sum(1)},
{
query: {status: "A"},
out: "uniq_id_name"
}
);
System.out.println(output);
答案 2 :(得分:0)
试试这个:
db.collection.aggregate(
{
$group: {
_id : "$the_field_to_be_grouped", // enter the field you want to group by
totalRequestId : { $sum : "$requestId" },
totaltelNum: { $sum : "$telNum" }
}
}
);