2016-10-05 1 views
-1

Ich bin mit Go Sprache und MongoDB mit mgo.v2 Fahrer und ich structAbfrage wo Summe von zwei Felder kleiner als gegebener Wert

type MarkModel struct { 
    ID   bson.ObjectId     `json: "_id,omitempty" bson: "_id,omitempty"` 
    Name  string       `json: "name" bson: "name"` 
    Sum   int        `json: "sum" bson: "sum"` 
    Delta  int        `json: "delta" bson: "delta"` 
} 

gerne haben muss ich alle finden, wo Sum + Delta < 1000 zum Beispiel ist. Im Moment lade ich alle und dann in Go code ich filtere aber ich möchte auf Abfrageebene filtern.
Wie man diese Abfrage macht?

Im Moment kehre ich alle mit

marks := []MarkModel{} 
c_marks := session.DB(database).C(marksCollection) 
err := c_marks.Find(bson.M{}).All(&marks) 
if err != nil { 
    panic(err) 
} 

und ich hier in for-Schleife in Go-Code auswählen, aber es ist nicht optimal (es ist eine schlechte Lösung).

+0

Etwas Code zu haben, der für die Abfrage einer Datenbank relevant ist d ein guter Startplatz sein. – evanmcdonnal

+0

@evanmcdonnal Ich habe aktuelle Abfrage hinzugefügt, aber es ist sehr schlechte Lösung, weil ich alle und dann in Go-Code-Filter holen –

Antwort

2

alle zu finden, wo sum + delta < 1000 ist, können Sie verwenden:

pipe := c.Pipe(
    []bson.M{ 
     bson.M{"$project": bson.M{"_id": 1, "name": 1, "sum": 1, "delta": 1, 
      "total": bson.M{"$add": []string{"$sum", "$delta"}}}}, 
     bson.M{"$match": bson.M{"total": bson.M{"$lt": 1000}}}, 
    }) 

Hier ist der Arbeitscode:

package main 

import (
    "fmt" 

    "gopkg.in/mgo.v2" 
    "gopkg.in/mgo.v2/bson" 
) 

func main() { 
    session, err := mgo.Dial("localhost") 
    if err != nil { 
     panic(err) 
    } 
    defer session.Close() 
    session.SetMode(mgo.Monotonic, true) // Optional. Switch the session to a monotonic behavior. 
    c := session.DB("test").C("MarkModel") 
    c.DropCollection() 
    err = c.Insert(&MarkModel{bson.NewObjectId(), "n1", 10, 1}, &MarkModel{bson.NewObjectId(), "n2", 20, 2}, 
     &MarkModel{bson.NewObjectId(), "n1", 100, 1}, &MarkModel{bson.NewObjectId(), "n2", 2000, 2}) 
    if err != nil { 
     panic(err) 
    } 

    pipe := c.Pipe(
     []bson.M{ 
      bson.M{"$project": bson.M{"_id": 1, "name": 1, "sum": 1, "delta": 1, 
       "total": bson.M{"$add": []string{"$sum", "$delta"}}}}, 
      bson.M{"$match": bson.M{"total": bson.M{"$lt": 1000}}}, 
     }) 
    r := []bson.M{} 
    err = pipe.All(&r) 
    if err != nil { 
     panic(err) 
    } 
    for _, v := range r { 
     fmt.Println(v["_id"], v["sum"], v["delta"], v["total"]) 
    } 
    fmt.Println() 

} 

type MarkModel struct { 
    ID bson.ObjectId `json: "_id,omitempty" bson: "_id,omitempty"` 
    Name string  `json: "name" bson: "name"` 
    Sum int   `json: "sum" bson: "sum"` 
    Delta int   `json: "delta" bson: "delta"` 
} 

Ausgang:

ObjectIdHex("57f62739c22b1060591c625f") 10 1 11 
ObjectIdHex("57f62739c22b1060591c6260") 20 2 22 
ObjectIdHex("57f62739c22b1060591c6261") 100 1 101 
1

Sie sollten wirklich die Aggregation Framework dafür verwenden. Dann wird es Server-Seite behandelt. so etwas wie:

db.table.aggregate(
    [ 
    { $project: { ID: 1, name : 1, total: { $add: [ "$Sum", "$Delta" ] } } }, 
    { $match : { total : { $gte: 1000 }}} 
    ] 
) 
Verwandte Themen