3

I am trying to make a query using the ObjectId, and normally in mongodb you would do something like this

db.collection.findOne({"_id":objectid("5d9d90e5ed645489aae6df64")})

Which this works when I do a normal query but in go lang it gives it the value of

ObjectIdHex("5d9d90e5ed645489aae6df64")

instead which does not lead to a valid query.

i have read through the mgo documentation many times trying to use

bson.ObjectId("5d9d90e5ed645489aae6df64")

but it still makes it a hex which I don't understand. I have tried a few different combination of things with no like they were pretty much just shots in the dark.

Go Lang Handlers

package userhandlers

import (
    "log"
    "net/http"
    //"fmt"
    //"go.mongodb.org/mongo-driver/bson/primitive"
    //"go.mongodb.org/mongo-driver/bson"
    "labix.org/v2/mgo/bson"

    //Services
    databaseservice "malikiah.io/services/databaseService"
    passwordservice "malikiah.io/services/passwordService"

    //Structs
    userstructs "malikiah.io/structs/userStructs"
    databasestructs "malikiah.io/structs/databaseStructs"
)

func LoginHandler(response http.ResponseWriter, request *http.Request) {
    response.Header().Set("Content-Type", "application/json")
    response.WriteHeader(http.StatusOK)

    databaseQuery := databasestructs.Find{
        ID: bson.ObjectId(request.FormValue("_id")),
        MongoCollection: "users",
        Criteria: "_id",
        CriteriaValue: "",
        FindAll: false,
    }
    log.Println(databaseQuery)
    databaseservice.Login(databaseQuery)
}

Go Lang Structs

package databasestructs

import (
    //"go.mongodb.org/mongo-driver/bson/primitive"
    "labix.org/v2/mgo/bson"
)

type Find struct {
    ID                      bson.ObjectId   `json:"_id,omitempty" bson:"_id,omitempty"`
    MongoCollection         string              `json:"mongoCollection,omitempty" bson:"mongoCollection,omitempty"`
    Criteria                string              `json:"criteria,omitempty" bson:"criteria,omitempty"`
    CriteriaValue           string              `json:"criteriaValue,omitempty" bson:"criteriaValue,omitempty"`
    FindAll                 bool                `json:"findAll,omitempty" bson:"findAll,omitempty"`
}

Go Lang Functions

package databaseservice

import (
    "context"
    "log"

    //Structs
    userstructs "malikiah.io/structs/userStructs"
    databasestructs "malikiah.io/structs/databaseStructs"

    //"go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "gopkg.in/mgo.v2/bson"

)

func Find(databaseQuery databasestructs.Find) (result string) {
    // Set client options
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

    // Connect to MongoDB
    client, err := mongo.Connect(context.TODO(), clientOptions)

    // Database name
    db := client.Database("malikiah")
    collection := db.Collection(databaseQuery.MongoCollection)

    if err != nil {
        log.Fatal(err)
    }

    if databaseQuery.Criteria == "_id" {
        log.Println(databaseQuery.ID)
        result := collection.FindOne(context.TODO(), bson.M{databaseQuery.Criteria: databaseQuery.ID}).Decode(&result)
        log.Println(result)
    } else if databaseQuery.Criteria == "" {

    } else if databaseQuery.FindAll == true {

    } else {

    }
    return
}
icza
  • 389,944
  • 63
  • 907
  • 827
Malikiah
  • 149
  • 2
  • 2
  • 13

1 Answers1

2

Note that labix.org/v2/mgo is not maintained anymore, if you want to use mgo, use github.com/globalsign/mgo instead. Or the new, official mongo-go driver.

bson.ObjectId is a type having string as its underlying type:

type ObjectId string

So when you fill your object like this:

databaseQuery := databasestructs.Find{
    ID: bson.ObjectId(request.FormValue("_id")),
    MongoCollection: "users",
    Criteria: "_id",
    CriteriaValue: "",
    FindAll: false,
}

bson.ObjectId(request.FormValue("_id")) is "nothing more" than a type conversion. You convert the hex object ID string to bson.ObjectId, but this is not what you want. You want to parse the hex object ID. For that, use the bson.ObjectIdHex() function:

databaseQuery := databasestructs.Find{
    ID: bson.ObjectIdHex(request.FormValue("_id")),
    MongoCollection: "users",
    Criteria: "_id",
    CriteriaValue: "",
    FindAll: false,
}

Note that bson.ObjectIdHex() will panic if the passed string is an invalid hex object ID. Use bson.IsObjectIdHex() to check it prior to calling bson.ObjectId(). For details, see Prevent runtime panic in bson.ObjectIdHex.

If you would use the official driver instead of mgo, you could use primitive.ObjectIDFromHex() function to create the ObjectId, e.g.:

id, err := primitive.ObjectIDFromHex(request.FormValue("_id"))
if err != nil {
    // Handle error
    return
}
// If no error, you may use it:
databaseQuery := databasestructs.Find{
    ID: id,
    // ...
}
icza
  • 389,944
  • 63
  • 907
  • 827
  • So I was using primitive before and I switched because I saw everyone using this. but This is the issue I run into using the primitive.ObjectIDFromHex(request.FormValue("_id")) ``` multiple-value primitive.ObjectIDFromHex() in single-value context ``` – Malikiah Oct 09 '19 at 11:01
  • @Malikiah See [Multiple values in single-value context](https://stackoverflow.com/questions/28227095/multiple-values-in-single-value-context/28233172#28233172). See edited answer. – icza Oct 09 '19 at 11:04
  • Yeah, Think It needs to be like this ``` objectID, _ := primitive.ObjectIDFromHex(request.FormValue("_id")) ``` – Malikiah Oct 09 '19 at 11:08
  • So now I am getting this error from my query result.... "cannot decode invalid into a string type" not sure what is happening now D: – Malikiah Oct 09 '19 at 11:11
  • @Malikiah I don't see your actual code now, but the one you posted in the question mixes `mgo` and `mongo-go` (the official driver). Be sure you don't do that. – icza Oct 09 '19 at 11:43
  • I changed it to only use the import of "go.mongodb.org/mongo-driver/bson/primitive" and it now comes back as an ObjectID(), which is correct. but maybe I dont understand what I should be doing for the decoding of the mongodb document result on my Find function. – Malikiah Oct 09 '19 at 11:55
  • @Malikiah The problem seems to be that you try to decode into `result`, which is a `string`. Query returns documents, which may be decoded into `struct`s for example. You can't decode a document into a `string`. – icza Oct 09 '19 at 11:57
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/200603/discussion-between-malikiah-and-icza). – Malikiah Oct 09 '19 at 12:07
  • Any idea where I can get more information on decoding into this and what I can and cant decode to? – Malikiah Oct 09 '19 at 12:09
  • Are you saying I should make a struct and then decode this information to a specific struct? – Malikiah Oct 09 '19 at 12:11