我试图从json形式的一些OSM数据中收集一些见解。这是我在MongoDB / PyMongo中使用的文档示例:
{"amenity": "post_office",
"name": "Dominion Road Postshop",
"created": {"uid": "10829",
"changeset": "607706",
"version": "5",
"user": "myfanwy",
"timestamp": "2007-11-24T12:41:04Z"},
"pos": [-36.8801299, 174.7495053],
"created_by": "Potlatch 0.5d",
"type": "node",
"id": "61076379"}
因此每个文档都有一个用户和一个便利设施。我想找到每个用户记录的每个便利设施的数量,除以每个用户记录的设施总量。
所以,为了帮助澄清这里我会用来查找每个人的代码片段:
查询1.查找每个用户记录的每个设施的数量:
amenity_per_user = coll.aggregate([{"$match":{"amenity":{"$exists":True}}},
{"$group":{"_id":{"user":"$created.user", "amenities":"$amenity"}, "count":{"$sum":1}}},
{"$sort":{"count":-1}}])
查询2.查找每个用户记录的设施数量:
results = coll.aggregate([{"$match":{"amenity":{"$exists":True}}},
{"$group":{"_id":"$created.user", "count":{"$sum":1}}},
{"$sort":{"count":-1}}])
两者的答案都是(每个限于5个结果):
Finding how many of each amenity each user records:
{u'_id': {u'amenities': u'parking', u'user': u'Rudy355'}, u'count': 1886}
{u'_id': {u'amenities': u'post_box', u'user': u'Rudy355'}, u'count': 547}
{u'_id': {u'amenities': u'telephone', u'user': u'Rudy355'}, u'count': 485}
{u'_id': {u'amenities': u'parking', u'user': u'myfanwy'}, u'count': 451}
{u'_id': {u'amenities': u'restaurant', u'user': u'Rudy355'}, u'count': 429}
Find how many amenities each user records:
{u'_id': u'Rudy355', u'count': 6321}
{u'_id': u'myfanwy', u'count': 951}
{u'_id': u'Robert Ancell', u'count': 599}
{u'_id': u'lcmortensen', u'count': 366}
{u'_id': u'Marks2000', u'count': 228}
现在我要做的是将每个用户的最高设施金额(即.Rudy355为停车设施制作了1886个条目)除以其总记录量(查询2)。 - 所以最终的结果是Rudy355在“停车”中录制了他的0.3个录音。市容。 - 1886/6321 = 0.3。
这就是我所要做的:
coll.aggregate([{"$match":{"amenity":{"$exists":True}}},
{"$group":{"_id":"$created.user", "user_count":{"$sum":1}}},
{"$group":{"_id":{"user":"$created.user", "amenities":"$amenity"}, "amenity_count":{"$sum":1},
"ucount":{"$push":"$user_count"}}},
{"$unwind":"$ucount"},
{"$project":{"$divide":{"$ucount", "$amenity_count"}}},
{"$sort":{"count":-1}}])
任何帮助都会很棒!
顺便说一句,我真的不喜欢使用$ push来保存' user_count'的价值。有没有人知道更好的方法来保存像这样的计算字段。
答案 0 :(得分:0)
您可以尝试以下聚合。 $push
amenity
保存每个count
及其record
,以便稍后用total
用户设施计算 [
{"$match":{"amenity":{"$exists":True}}},
{"$group":{"_id":{"user":"$created.user", "amenity":"$amenity"}, "count":{"$sum":1}}},
{"$group":{"_id":"$_id.user", "total":{"$sum":"$count"}, "amenities":{"$push":{amenity:"$_id.amenity","count":"$count"}}}},
{"$unwind":"$amenities"},
{"$project:{"_id":0,"user":"$_id", "amenity":"$amenities.amenity", record":{"$divide":{"$amenities.count", "$total"}}}},
{"$sort":{"record":-1}}
]
。
{"user":"Rudy355", "amenity":"parking", "record":0.3}
你应该有如下的输出。
private static Object[] getCompositeKey(
final Object object )
{
final List<Object> keys = new ArrayList<>();
for( final Field field : object.getClass().getDeclaredFields() ) {
try {
field.setAccessible( true );
if( field.getAnnotation( Primary.class ) != null ) {
keys.add( field.get( object ) );
}
} catch( final Exception e ) {
//handle exception
}
}
if( keys.isEmpty() ) {
//no keys
return new Object[]{};
}
return keys.toArray();
}