How to convert the following aggregate query to bson and execute in golang

huangapple go评论76阅读模式
英文:

How to convert the following aggregate query to bson and execute in golang

问题

这是我想从代码中运行的查询。

db.apnSummary.aggregate([{"$match":{"mid":{"$in":["81"]}}},{"$group":{"_id":"$mid","clicked":{"$sum":"$open"},"delivered":{"$sum":"$delivered"},"failed":{"$sum":"$failed"},"freqDrop":{"$sum":"$freqDrop"},"published":{"$sum":"$published"},"sent":{"$sum":"$sent"}}}]);

从代码中准备的查询:-

[{"$match":{"date":{},"mid":{"$in":[81]}}},{"$group":{"_id":"$mid","clicked":{"$sum":"$open"},"delivered":{"$sum":"$delivered"},"failed":{"$sum":"$failed"},"freqDrop":{"$sum":"$freqDrop"},"published":{"$sum":"$published"},"sent":{"$sum":"$sent"}}}]

当我执行这个查询时,我得到了结果,但是当我从代码中执行查询时,它没有给我提供结果,而是给出了空白数据。
我的代码如下:-

func GetApnDataFromMongo(data utils.Data, clientName string) (utils.Results, error) {
	result := utils.Results{}

	date := bson.M{}
	messageId := bson.M{}
	if len(data.MessageId) > 0 {
		messageId = bson.M{"$in": convertToInt(data.MessageId)}
	}

	if data.DateFrom != "" && data.DateTo != "" {
		date = bson.M{"$gte": data.DateFrom, "$lte": data.DateTo}
	}

	primary_collection := bson.M{"$match": bson.M{"mid": messageId, "date": date}}
	group_collection := bson.M{"$group": bson.M{"_id": "$mid", "published": bson.M{"$sum": "$published"}, "sent": bson.M{"$sum": "$sent"}, "failed": bson.M{"$sum": "$failed"}, "freqDrop": bson.M{"$sum": "$freqDrop"}, "delivered": bson.M{"$sum": "$delivered"}, "clicked": bson.M{"$sum": "$open"}}}

	fullquery := []bson.M{primary_collection, group_collection}
	jsonString, _ := json.Marshal(fullquery)
	logrus.Info(fmt.Sprintf("Final query prepared is as following %+v", string(jsonString)))
	ctx := context.Background()
	conn, err := utils.GetMongoConnection()
	if err != nil {
		logrus.Errorf("Error connecting to mongo %+v", err)
		return result, err
	}
	logrus.Info("clientName %+v", clientName)
	resultData, err := conn.Database(clientName).Collection("apnSummary").Aggregate(ctx, mongo.Pipeline(primary_collection, group_collection))
	if err != nil {
		logrus.Errorf("Error querying %+v", err)
		return result, err
	}
	mongodata := []utils.MonogResponse{}
	resultData.All(ctx, &mongodata)
	fmt.Println(mongodata)
	result = PrepareMongoResponse(mongodata)
	return result, nil
}

func PrepareMongoResponse(data []utils.MonogResponse) utils.Results {
	result := utils.Results{}
	for _, res := range data {
		result.Failure.Mid = append(result.Failure.Mid, res.Mid)
		result.Delivered.Mid = append(result.Delivered.Mid, res.Mid)
		result.Frequency.Mid = append(result.Frequency.Mid, res.Mid)
		result.Sent.Mid = append(result.Sent.Mid, res.Mid)
		result.Click.Mid = append(result.Click.Mid, res.Mid)
		result.Failure.Count = append(result.Failure.Count, res.Failed)
		result.Delivered.Count = append(result.Delivered.Count, res.Delivered)
		result.Frequency.Count = append(result.Frequency.Count, res.FreqDrop)
		result.Sent.Count = append(result.Sent.Count, res.Sent)
		result.Click.Count = append(result.Click.Count, res.Clicked)
	}
	return result
}

func convertToInt(data []string) []int {
	intData := []int{}
	for _, dt := range data {
		intV, _ := strconv.Atoi(dt)
		intData = append(intData, intV)
	}
	return intData
}

<details>
<summary>英文:</summary>

This is the following query that I want to run it from code.

db.apnSummary.aggregate([{&quot;$match&quot;:{&quot;mid&quot;:{&quot;$in&quot;:[&quot;81&quot;]}}},{&quot;$group&quot;:{&quot;_id&quot;:&quot;$mid&quot;,&quot;clicked&quot;:{&quot;$sum&quot;:&quot;$open&quot;},&quot;delivered&quot;:{&quot;$sum&quot;:&quot;$delivered&quot;},&quot;failed&quot;:{&quot;$sum&quot;:&quot;$failed&quot;},&quot;freqDrop&quot;:{&quot;$sum&quot;:&quot;$freqDrop&quot;},&quot;published&quot;:{&quot;$sum&quot;:&quot;$published&quot;},&quot;sent&quot;:{&quot;$sum&quot;:&quot;$sent&quot;}}}]);

Query prepared from code :-
```
[{&quot;$match&quot;:{&quot;date&quot;:{},&quot;mid&quot;:{&quot;$in&quot;:[81]}}},{&quot;$group&quot;:{&quot;_id&quot;:&quot;$mid&quot;,&quot;clicked&quot;:{&quot;$sum&quot;:&quot;$open&quot;},&quot;delivered&quot;:{&quot;$sum&quot;:&quot;$delivered&quot;},&quot;failed&quot;:{&quot;$sum&quot;:&quot;$failed&quot;},&quot;freqDrop&quot;:{&quot;$sum&quot;:&quot;$freqDrop&quot;},&quot;published&quot;:{&quot;$sum&quot;:&quot;$published&quot;},&quot;sent&quot;:{&quot;$sum&quot;:&quot;$sent&quot;}}}]
```
when I execute this query I get the results but when I do the query from code it does not provide me result gives blank data.
my code is as following:- 

func GetApnDataFromMongo(data utils.Data, clientName string) (utils.Results, error) {
result := utils.Results{}

date := bson.M{}
messageId := bson.M{}
if len(data.MessageId) &gt; 0 {
	messageId = bson.M{&quot;$in&quot;: convertToInt(data.MessageId)}
}

if data.DateFrom != &quot;&quot; &amp;&amp; data.DateTo != &quot;&quot; {
	date = bson.M{&quot;$gte&quot;: data.DateFrom, &quot;$lte&quot;: data.DateTo}
}

primary_collection := bson.M{&quot;$match&quot;: bson.M{&quot;mid&quot;: messageId, &quot;date&quot;: date}}
group_collection := bson.M{&quot;$group&quot;: bson.M{&quot;_id&quot;: &quot;$mid&quot;, &quot;published&quot;: bson.M{&quot;$sum&quot;: &quot;$published&quot;}, &quot;sent&quot;: bson.M{&quot;$sum&quot;: &quot;$sent&quot;}, &quot;failed&quot;: bson.M{&quot;$sum&quot;: &quot;$failed&quot;}, &quot;freqDrop&quot;: bson.M{&quot;$sum&quot;: &quot;$freqDrop&quot;}, &quot;delivered&quot;: bson.M{&quot;$sum&quot;: &quot;$delivered&quot;}, &quot;clicked&quot;: bson.M{&quot;$sum&quot;: &quot;$open&quot;}}}

fullquery := []bson.M{primary_collection, group_collection}
jsonString, _ := json.Marshal(fullquery)
logrus.Info(fmt.Sprintf(&quot;Final query prepared is as following %+v&quot;, string(jsonString)))
ctx := context.Background()
conn, err := utils.GetMongoConnection()
if err != nil {
	logrus.Errorf(&quot;Error connecting to mongo %+v&quot;, err)
	return result, err
}
logrus.Info(&quot;clientName %+v&quot;, clientName)
resultData, err := conn.Database(clientName).Collection(&quot;apnSummary&quot;).Aggregate(ctx, mongo.Pipeline(primary_collection, group_collection))
if err != nil {
	logrus.Errorf(&quot;Error querying %+v&quot;, err)
	return result, err
}
mongodata := []utils.MonogResponse{}
resultData.All(ctx, &amp;mongodata)
fmt.Println(mongodata)
result = PrepareMongoResponse(mongodata)
return result, nil

}

func PrepareMongoResponse(data []utils.MonogResponse) utils.Results {
result := utils.Results{}
for _, res := range data {
result.Failure.Mid = append(result.Failure.Mid, res.Mid)
result.Delivered.Mid = append(result.Delivered.Mid, res.Mid)
result.Frequency.Mid = append(result.Frequency.Mid, res.Mid)
result.Sent.Mid = append(result.Sent.Mid, res.Mid)
result.Click.Mid = append(result.Click.Mid, res.Mid)
result.Failure.Count = append(result.Failure.Count, res.Failed)
result.Delivered.Count = append(result.Delivered.Count, res.Delivered)
result.Frequency.Count = append(result.Frequency.Count, res.FreqDrop)
result.Sent.Count = append(result.Sent.Count, res.Sent)
result.Click.Count = append(result.Click.Count, res.Clicked)
}
return result
}

func convertToInt(data []string) []int {
intData := []int{}
for _, dt := range data {
intV, _ := strconv.Atoi(dt)
intData = append(intData, intV)
}
return intData
}

答案1

得分: 1

如果date过滤器缺失,不要添加一个&quot;date&quot;: {}过滤器,该过滤器会筛选出&quot;date&quot;为空对象的文档,显然在你的情况下不适用。如果没有日期过滤器,请在$match阶段中省略date

对于messageID和所有其他过滤器也是同样的处理方式。

你可以这样做:

matchDoc := bson.M{}
if len(data.MessageId) &gt; 0 {
	matchDoc[&quot;mid&quot;] = bson.M{&quot;$in&quot;: convertToInt(data.MessageId)}
}
if data.DateFrom != &quot;&quot; &amp;&amp; data.DateTo != &quot;&quot; {
	matchDoc[&quot;date&quot;] = bson.M{&quot;$gte&quot;: data.DateFrom, &quot;$lte&quot;: data.DateTo}
}
primary_collection := bson.M{&quot;$match&quot;: matchDoc}

注意:你的原始查询有效是因为你在其中省略了date:{}过滤器!

英文:

If date filter is missing, do not add a &quot;date&quot;: {} filter, that filters for documents where &quot;date&quot; is an empty object, which obviously don't hold in your case. Leave out date from the $match stage if you don't have a date filter!

Same goes for messageID and all other filters.

You may do it like this:

matchDoc := bson.M{}
if len(data.MessageId) &gt; 0 {
	matchDoc[&quot;mid&quot;] = bson.M{&quot;$in&quot;: convertToInt(data.MessageId)}
}
if data.DateFrom != &quot;&quot; &amp;&amp; data.DateTo != &quot;&quot; {
	matchDoc[&quot;date&quot;] = bson.M{&quot;$gte&quot;: data.DateFrom, &quot;$lte&quot;: data.DateTo}
}
primary_collection := bson.M{&quot;$match&quot;: matchDoc}

Note: your original query works because you left out the date:{} filter from it!

huangapple
  • 本文由 发表于 2022年8月5日 19:32:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/73249085.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定