所以我对数据库(mongodb)有一些查询,它将按值字段排序结果。
all := EValues{}
err := con.Find(bson.M{"name": "somename}).Sort("-value").All(&all)
Json输出如下:
"values": [
{
"user_name": "guest7485",
"value": 8911,
"value_date": "2016-03-09T14:40:34.512Z"
},
{
"user_name": "guest7485",
"value": 539,
"value_date": "2016-03-07T14:11:05.217Z"
},
{
"user_name": "guest7485",
"value": 221,
"value_date": "2016-03-07T14:11:08.853Z"
},
{
"user_name": "guest7485",
"value": 77,
"value_date": "2016-03-07T14:11:12.377Z"
}
]
在我的json响应中,我需要添加参数" position"对于所有结果,它应该基本上等于1 - 第一结果,2秒结果等等。所以我的最终输出应该是:
"values": [
{
"position": 1,
"user_name": "guest7485",
"value": 8911,
"value_date": "2016-03-09T14:40:34.512Z"
},
{
"position": 2,
"user_name": "guest7485",
"value": 539,
"value_date": "2016-03-07T14:11:05.217Z"
},
{
"position": 3,
"user_name": "guest7485",
"value": 221,
"value_date": "2016-03-07T14:11:08.853Z"
},
{
"position": 4,
"user_name": "guest7485",
"value": 77,
"value_date": "2016-03-07T14:11:12.377Z"
}
]
我想知道如何用mgo来解决这个问题并且总的来说,如果有人能给我最有效的方法来解决这个问题,我会非常感激。
更新
Evalues的定义如下:
type EValue struct {
ID bson.ObjectId `json:"-" bson:"_id,omitempty"`
Name string `json:"-" bson:"name"`
UserId bson.ObjectId `json:"-" bson:"userId"`
UserName string `json:"user_name" bson:"userName"`
Value int64 `json:"value" bson:"value"`
AddedTime time.Time `json:"value_date" bson:"addedTime"`
}
type EValues []EValue
答案 0 :(得分:0)
向EValue添加位置字段:
type EValue struct {
... other fields here
Position int `json:"position" bson:"-"`
}
循环遍历db结果并设置字段:
for i := range all {
all[i].Position = i + 1
}
将结果标记为JSON。
答案 1 :(得分:0)
使用MongDB 3.2,可以使用 $unwind
运算符完成此操作,您可以在其中传递包含字段path
的对象和将保留的字段includeArrayIndex
数组索引:
pipeline = [
{ "$match": {"name": "somename"} },
{ "$unwind": { "path": "$values", "includeArrayIndex": "position" } },
{
"$project": {
"name": 1,
"newarray.position": "$position",
"newarray.user_name": "$values.user_name",
"newarray.value_date": "$values.value_date",
"newarray.value": "$values.value",
}
},
{
"$group": {
"_id": "$name",
"values": { "$push": "$newarray" }
}
}
]
db.test.aggregate(pipeline);
<强>输出强>
> db.test.aggregate(pipeline).pretty();
{
"_id" : "somename",
"values" : [
{
"position" : NumberLong(0),
"user_name" : "guest8911",
"value_date" : "2016-03-09T14:40:34.512Z",
"value" : 8911
},
{
"position" : NumberLong(1),
"user_name" : "guest7485",
"value_date" : "2016-03-07T14:11:05.217Z",
"value" : 539
},
{
"position" : NumberLong(2),
"user_name" : "guest7485",
"value_date" : "2016-03-07T14:11:08.853Z",
"value" : 221
},
{
"position" : NumberLong(3),
"user_name" : "guest7485",
"value_date" : "2016-03-07T14:11:12.377Z",
"value" : 77
}
]
}
>
如果mgo驱动程序不支持这种方法,那么一种不那么有效的方法就是使用Map-Reduce。以下mongo shell示例演示了如何运行该操作:
填充测试集合:
db.test.insert({
"name": "somename",
"values": [
{
"user_name": "guest8911",
"value": 8911,
"value_date": "2016-03-09T14:40:34.512Z"
},
{
"user_name": "guest7485",
"value": 539,
"value_date": "2016-03-07T14:11:05.217Z"
},
{
"user_name": "guest7485",
"value": 221,
"value_date": "2016-03-07T14:11:08.853Z"
},
{
"user_name": "guest7485",
"value": 77,
"value_date": "2016-03-07T14:11:12.377Z"
}
]
})
运行以下map-reduce操作:
> mr = db.runCommand({
"mapreduce": "test",
"map": function() {
var arr = []
for(var i=0; i < this.values.length; i++){
var val = this.values[i];
val["position"] = i+1;
arr.push(val);
}
emit(this._id, arr);
},
"reduce" : function() {},
"out": "test_keys"
})
查询结果集合:
> db[mr.result].find().pretty()
{
"_id" : ObjectId("56e18ab84b9018ec86d2a6bd"),
"value" : [
{
"user_name" : "guest8911",
"value" : 8911,
"value_date" : "2016-03-09T14:40:34.512Z",
"position" : 1
},
{
"user_name" : "guest7485",
"value" : 539,
"value_date" : "2016-03-07T14:11:05.217Z",
"position" : 2
},
{
"user_name" : "guest7485",
"value" : 221,
"value_date" : "2016-03-07T14:11:08.853Z",
"position" : 3
},
{
"user_name" : "guest7485",
"value" : 77,
"value_date" : "2016-03-07T14:11:12.377Z",
"position" : 4
}
]
}
>
现在给出上面的列表,您可以使用MapReduce
在mgo中汇编查询job := mgo.MapReduce{
Map: "function(){var arr=[];for(var i=0;i<this.values.length; i++){var val=this.values[i];val['position']=i+1;arr.push(val);};emit(this._id,arr);}",
Reduce: "function() { }",
}
var result []struct { Id int "_id"; Value []EValue }
_, err := collection.Find(nil).MapReduce(job, &result)
if err != nil {
panic(err)
}
for _, item := range result {
fmt.Println(item.Value)
}
有关详细信息,请查看文档:{{3}}: