duai0935
2016-10-07 01:56 阅读 209

需要使用mgo在删除中使用$ add和$ gt(Golang && MongoDB)

I'm using Golang as my backend and MongoDB as the database for my web application. I'm in need of adding two values and check if the value in the database is greater than the added value and if it is, I need to remove the row from the MongoDB.
The code which I wrote is as follows

err, err1 := c.RemoveAll(bson.M{
        "currenttime": bson.M{
            "$gt": bson.M{
                "$add": []interface{}{time.Now().Unix(),"100"},
            },
        },
     })

FYI: I wrote the sample code for MongoDB but this is not working as well

db.Collection.remove(
   {currenttime:{
        $gt:{
                $add:[100,100]
             }
              }
    }
 )

Please let me know if this is possible. And please give me any alternative way to do this.
Thanks

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

4条回答 默认 最新

  • 已采纳
    doufu1950 doufu1950 2016-10-07 05:44

    1- If you need to remove rows with field e.g. time > t + 10 from the MongoDB, you do't need $add, you may use:

    info, err := c.RemoveAll(bson.M{"time": bson.M{"$gt": t + 10}})
    if err != nil {
        panic(err)
    }
    

    Here is the working code:

    package main
    
    import (
        "fmt"
        "time"
    
        "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("Model")
        c.DropCollection()
        t := time.Now().UTC().Unix()
        err = c.Insert(
            &Model{bson.NewObjectId(), "n1", t},
            &Model{bson.NewObjectId(), "n2", t + 50},
            &Model{bson.NewObjectId(), "n3", t + 100},
            &Model{bson.NewObjectId(), "n4", t + 150})
        if err != nil {
            panic(err)
        }
        r := []Model{}
        err = c.Find(nil).All(&r)
        if err != nil {
            panic(err)
        }
        fmt.Println(r)
    
        info, err := c.RemoveAll(bson.M{"time": bson.M{"$gt": t + 10}})
        if err != nil {
            panic(err)
        }
        fmt.Println(info)
    
        r2 := []Model{}
        err = c.Find(nil).All(&r2)
        if err != nil {
            panic(err)
        }
        fmt.Println(r2)
    }
    
    type Model struct {
        ID   bson.ObjectId `json: "_id,omitempty" bson: "_id,omitempty"`
        Name string        `json: "name" bson: "name"`
        Time int64         `json: "time" bson: "time"`
    }
    

    output:

    [{ObjectIdHex("57f7354cc3176906c0ca7516") n1 1475818828} {ObjectIdHex("57f7354cc3176906c0ca7517") n2 1475818878} {ObjectIdHex("57f7354cc3176906c0ca7518") n3 1475818928} {ObjectIdHex("57f7354cc3176906c0ca7519") n4 1475818978}]
    &{0 3 3 <nil>}
    [{ObjectIdHex("57f7354cc3176906c0ca7516") n1 1475818828}]
    

    2- For $add, see:
    Query where sum of two fields is less than given value
    https://docs.mongodb.com/manual/reference/operator/aggregation/add/

    点赞 评论 复制链接分享
  • doumao9363 doumao9363 2016-10-07 03:49

    Here is what i propose. You can do it in two steps rather then in one.

    first find all the entries that matches you delete criteria. Then delete those matching entries using remove() query.

    The below query will return all the documents with currentTime greater then 200.(add 100 to 100).

    db.Collection.aggregate(
       [
         { $project: { currentTime: 1, current_time:{ $gt: [ "$currentTime", { $add: [ 100,100 ] } ] } }}
       ]
    )
    

    i created a sample collection with the following data :

    { "_id" : ObjectId("57f714f0b30252798d8a2988"), "currentTime" : 1000 }
    { "_id" : ObjectId("57f714f4b30252798d8a2989"), "currentTime" : 100 }
    { "_id" : ObjectId("57f714f7b30252798d8a298a"), "currentTime" : 150 }
    { "_id" : ObjectId("57f714fcb30252798d8a298b"), "currentTime" : 1250 }
    

    and the result of the above query on this collection is :

    { "_id" : ObjectId("57f714f0b30252798d8a2988"), "currentTime" : 1000, "current_time" : true }
    { "_id" : ObjectId("57f714f4b30252798d8a2989"), "currentTime" : 100, "current_time" : false }
    { "_id" : ObjectId("57f714f7b30252798d8a298a"), "currentTime" : 150, "current_time" : false }
    { "_id" : ObjectId("57f714fcb30252798d8a298b"), "currentTime" : 1250, "current_time" : true }
    

    as you can see from the results that documents which has currentTime as 100 and 150 have returned false since they are less then 200.

    点赞 评论 复制链接分享
  • dongrang2140 dongrang2140 2016-10-07 04:40

    Now this is the way to remove your documents :

    What you were doing :

    you cannot simply use $add as this operator only works with aggregate system

    What you should do actually

    1. Get All Records to be deleted using Aggregate methodology
    2. Run a loop over them and remove

    Example:

    var cursor = db.Collection.aggregate([ { $match: { currenttime: { $gt:{ $add:[100,100] }}}} ]); cursor.forEach(function (doc){ db.Collection.remove({"_id": doc._id}); });

    点赞 评论 复制链接分享
  • dpt62283 dpt62283 2016-10-07 08:05

    Based on your sample code, I can observe that you use MongoDB remove command to filter only values of field currenttime greater than a particular value.

    If you intend to delete certain documents after they passed certain time, you should check out MongoDB Time To Live feature. Where you can Expire Data from Collections

    For example, you can specify :

    db.collection.createIndex( { "field_containing_time": 1 }, { expireAfterSeconds: 3600 } )
    

    To expire any documents from a collection after one hour. See also TTL Indexes

    Although this answer contain no Golang related code, if this is what you are trying to do in the big picture, it may be beneficial for your use case.

    点赞 评论 复制链接分享

相关推荐