2

How do I use a given slice to generate a bson.A? I need this to make dynamic queries.

I am upgrading from mongo-go-driver alpha to beta 0.2.0, and this has become a major change in my project since the API is different now.

https://godoc.org/github.com/mongodb/mongo-go-driver/bson

input := []string{"bar", "world"}
//expected output
bson.A{"bar", "world"}
faraonc
  • 61
  • 1
  • 6

3 Answers3

6

Not sure if you ever found your answer, but I battled with this for an hour+ yesterday.

I'm not positive this will solve what you're asking. I assume you're trying to build a filter from your input. Ultimately I did not use a bson.A when I was trying to pass an array.

Situation: Trying to build a filter and one of the bson.D elements is an array.

I thought I needed to use bson.A.

My initial assumption:

return bson.D{
  {"uuid", request.Uuid},
  {"action", request.Action},
  {"resource", bson.D{{"$in", bson.A{resourceStrings}}}},
}

where resourceStrings is a slice of strings.

However this will ultimately build a filter that looks like FILTER : [ {resource [{$in [[Orgs::Organizations::1 Orgs::Organizations::* Orgs::Organizations Orgs::*]]}]}]

*Note that the $in method is looking for an array of arrays here.

What we want is: FILTER : [{uuid 80} {action UpdateOrganization} {resource [{$in [Orgs::Organizations::1 Orgs::Organizations::* Orgs::Organizations Orgs::*]}]}]

If we pass in a literal array of strings it will work...

return bson.D{
  {"uuid", request.Uuid},
  {"action", request.Action},
  {"resource", bson.D{{"$in", bson.A{"Orgs::Organizations::1", "Orgs::Organizations::*", "Orgs::Organizations", "Orgs::*"}}}},
}

After some trial and error I found that bson.D will directly accept the array.

ultimately I solved the issue thus

return bson.D{
  {"uuid", request.Uuid},
  {"action", request.Action},
  {"resource", bson.D{{"$in", resourceStrings}}},
}

Taking your example literally - if you're simply trying to marshal an array to a bson.A try:

bson.A{input}

Timmy
  • 366
  • 5
  • 10
3

So bson.A underlying type is []interface{},

I could just use append to it like a slice

faraonc
  • 61
  • 1
  • 6
0

Here is my code to delete multiple documents based on ID which are present in another collection.
We first collect all the IDs from one collection and add to a slice. Then we delete documents in another collection using DeleteMany()

I am showing the relevant code to keep the code clean.

Json

[
    {
        "id": "602607bcfdc0548bfebbd0c7",
        "subject": "SUBJECT",
        "system": "SYSTEM",
        "board": "BOARD",
        "series": "SERIES",
        "paper": "PAPER",
        "year": "2021",
        "month": "February",
        "question_hex_ids": [
            "602607bcfdc0548bfebbd0c4",
            "602607bcfdc0548bfebbd0c5",
            "602607bcfdc0548bfebbd0c6"
        ]
    }
]

Code


    var hexIDCollection []primitive.ObjectID
    database := db.Conn.Database("mydatabase")
    question := database.Collection("questions")

    //Iterating to collect IDs from paper
    for k, _ := range mystruct.question_hex_ids {

        // fetching all IDs and appending to slice
        ids := mystruct.question_hex_ids[k]
        hexID, err := primitive.ObjectIDFromHex(ids)
        if err != nil {
            fmt.Println("ObjectIDFromHex ERROR", err)
        }

        //Populating a slice of all the IDs
        hexIDCollection = append(hexIDCollection, hexID)
    }

    filter := bson.D{
        {"_id", bson.D{{"$in", hexIDCollection}}}, }

    deleteResult, err1 := question.DeleteMany(ctx, filter)
    if err != nil {
        fmt.Println("Question Deletion Error", err1)
    }

    fmt.Println("All questions Deleted: ", deleteResult)
Muhammad Tariq
  • 3,318
  • 5
  • 38
  • 42