Golang在json响应中获取数组索引值
Posted
技术标签:
【中文标题】Golang在json响应中获取数组索引值【英文标题】:Golang get array index value in json response 【发布时间】:2016-06-25 11:14:06 【问题描述】:所以我对数据库(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 响应中,我需要添加参数“位置”,对于所有结果,它应该基本上等于 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
【问题讨论】:
你检查过这个吗?***.com/questions/32908186/… @aacanakin 我知道 .Iter() 但我再次不确定如何将位置注入 json 响应。 显示 EValues 的定义。 @MuffinTop 添加了定义。 【参考方案1】:给EValue添加一个位置字段:
type EValue struct
... other fields here
Position int `json:"position" bson:"-"`
遍历db结果并设置字段:
for i := range all
all[i].Position = i + 1
将结果编组为 JSON。
【讨论】:
这是最有效的方法吗,因为我真的不喜欢再次遍历整个数组的想法? 这可能是最有效的方式。即使不是,与解组 BSON 值或编组 JSON 值的成本相比,成本也可以忽略不计。【参考方案2】:在 MongDB 3.2 中,这可以使用 $unwind
运算符来完成,您可以在其中传递带有字段 path
和字段 includeArrayIndex
的对象,该字段将保存数组索引: p>
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)
更多详情请查看文档:https://godoc.org/labix.org/v1/mgo#MapReduce:
【讨论】:
以上是关于Golang在json响应中获取数组索引值的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Guzzle 和 Laravel 从 JSON 响应中提取单个数组值