Search code examples
mongodbgobson

How can I compare two bson.M data sets using Golang


I have the following code which retrieves two data sets from two different collections in a MongoDB database

    opts := options.Find()
    opts.SetProjection(bson.M{
        "productId": 1,
        "_id": 0,
    })

    cursor, err := currentProductsCollection.Find(ctx, bson.M{}, opts)
    var oldProducts []bson.M
    err = cursor.All(ctx, &oldProducts)

    cursor, err = newProductsCollection.Find(ctx, bson.M{}, opts)
    var newProducts []bson.M
    err = cursor.All(ctx, &newProducts)

I want to be able to compare oldProducts with newProducts to find out what new productId's have appeared and which old productId's have disappeared.

The two variables have both loaded fine and I can happily inspect them in the debugger, but I can't seem to find a way of comparing them. I had hoped to be able to range over each in turn doing a lookup on the other and getting a couple of slices of missing values but I can't find any way to do it.

I've been going round the houses with this for the last three hours so if anyone has any suggestions I would more than welcome them.

I am using the vanilla go.mongodb.org/mongo-driver drivers, not mgo


Solution

  • Create map for both old product and new product by product id

    oldProductsMap = make(map[interface{}]bson.M)
    for _,oldp := range oldProducts {
       oldProductsMap[oldp["productId"]] = oldp
    }
    
    newProductsMap = make(map[interface{}]bson.M)
    for _,newp :=range newProducts {
       newProductsMap[newp["productId"]] = newp
    }
    

    Then for the disappeared product check old product is in newProductsMap. If not then the product disappeared

    var disProducts []bson.M
    for _,oldp := range oldProducts {
       if _, ok := newProductsMap[oldp["productId"]]; !ok {
           disProducts = append(disProducts, oldp) 
       }
    }
    

    For newly appeared product check new product is in oldProductsMap. If not then the product newly appeared.

    var appProducts []bson.M
    for _,newp := range newProducts {
       if _, ok := oldProductsMap[newp["productId"]]; !ok {
           appProducts = append(appProducts, oldp)
       }
    }
    

    Note : You can do this portion when create map for new product also