How to mongo-driver text seach - mongodb

I am using go.mongodb.org/mongo-driver
I want to search in mongo atlas by $search. I want to find a way to search text from all fields
func FindHuman(){
clientOptions := options.Client().ApplyURI(os.Getenv("DB"))
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
return nil, err
}
db := client.Database("back_office").Collection("Human")
search := bson.M{"$text": bson.M{"$search": "John"}}
cur, err := db.Find(context.TODO(), search)
var humans []humanStruck
var human humanStruck
for cur.Next(context.Background()) {
err = cur.Decode(&human)
humans = append(humans, human)
}
fmt.Println(humans)
}
However I get the following error
(IndexNotFound) text index required for $text query

Related

Connect Go to Mongo Atlas and find documents

I'm a newbie to Go and trying to connect my sample application to Mongo Atlas
I`ve create a cluster in Mongo Atlas which has the following information:
I'm trying to retrieve documents from the collection but it fails to find any:
I'm able to connect to the DB, but when I run .Find() then I get an error of document is nil
When i run a specific query (for email) then it works.
When i run a general query (context.TODO()) then it is not working
What am I missing here?
const connectionStr = "mongodb+srv://" + MONGO_USER + ":" + MONGO_PASSWORD + "#cluster0.3ymvqrs.mongodb.net/?retryWrites=true&w=majority"
serverAPIOptions := options.ServerAPI(options.ServerAPIVersion1)
clientOptions := options.Client().
ApplyURI(connectionStr).
SetServerAPIOptions(serverAPIOptions)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatal(err, client)
}
// Select the database and collection
database := client.Database("sample_mflix")
commentsCollection := database.Collection("comments")
// Retrieve documents from the collection
// cursor, err := commentsCollection.Find(context.TODO(), nil) // not working
cursor, err := commentsCollection.Find(ctx, bson.M{"email": "roxanne_mckee#gameofthron.es"}) // working
if err != nil {
log.Fatal(err)
}
defer cursor.Close(context.TODO())

error from convert ObjectIDFromHex from mongodb

I have a problem finding an objectid through the query param called id.
I can see the id that arrives at the function until the moment of doing the query.
But when I try to use ObjectIDFromHex it returns 00000000000000000000000 and doesn't get the document from mongodb.
I'll leave a screenshot so you can see the full problem.
screenshot with IDE
The code is this.
func RetrieveUser(ID string) (models.User, error) {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
db := MongoCN.Database("mydatabase")
col := db.Collection("users")
var user models.User
objID, _ := primitive.ObjectIDFromHex(ID)
fmt.Println(ID)
fmt.Println(objID)
condition := bson.M{
"_id": objID,
}
err := col.FindOne(ctx, condition).Decode(&user)
user.Password = ""
if err != nil {
fmt.Println("User not found" + err.Error())
return user, err
}
return user, nil
}

How to exclude specific key from mongodb lookup in go?

I have the logic to query data from MongoDB to produce Kafka messages. I want to exclude a specific key in MongoDB. Please help. (ex. key name: def)
//1. search mongodb
connetionMongodbInfo := common.MongodbIpInfo()
clientOptions := options.Client().ApplyURI(connetionMongodbInfo)
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {return result, common.CCErrServiceUnavailable}
defer client.Disconnect(context.TODO())
backupCollection := client.Database(common.MongodbName()).Collection(common.MongodbCollection())
In the logic below, it seems that a statement excluding key def should be added.
cursor, err := backupCollection.Find(context.TODO(), bson.D{{"abc",abc}})
if err != nil {return result, common.CCErrServiceUnavailable}
Below is the logic to receive mongodb data and produce kafka message.
//2. produce kafka message
for cursor.Next(context.TODO()) {
var elem bson.M
err := cursor.Decode(&elem)
if err != nil {return result, common.CCErrServiceUnavailable}
JsonData, jsonErr := json.Marshal(elem)
if jsonErr != nil {return result, common.CCErrServiceUnavailable}
var data map[string]interface{}
json.Unmarshal([]byte(JsonData), &data)enter code here
str := fmt.Sprint(data["abc"])
common.SendMessageAsync(topic, str, string(JsonData))
}

cannot transform type bson.Raw to a BSON Document: length read exceeds number of bytes available

Trying to add some json data from an API to a database but get this error when trying
cannot transform type bson.Raw to a BSON Document: length read exceeds number of bytes available. length=259839 bytes=1919951
I know the json is well below mongodb limit of 16mb, ive even tried importing just some small data from this api but get the same error. I was able to import just a test struct to see it was working but my api data doesnt seem to be going through. Is there some type of conversion i need to do with my api data? Here is my golang code
func main(i int) {
url := "http://api.open-notify.org/astros.json"
resp, err := http.Get(url)
if err != nil {
log.Fatalln(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
// _ = body
log.Println(string(body))
clientOptions := options.Client().ApplyURI("mongodb+srv://username:password#cluster0-slmxe.mongodb.net/dbtest?retryWrites=true&w=majority")
// Connect to MongoDB
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
}
err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected to database")
collection := client.Database("dbtest").Collection("test")
insertResult, err := collection.InsertOne(context.TODO(), body)
if err != nil {
log.Fatal(err)
}
fmt.Println("Inserted", insertResult.InsertedID)
}
You need to wrap your json with bson.D to able to send the data to Mongodb. This is to build representation for native go types. Example below:
// insert the document {name: "Alice"}
res, err := coll.InsertOne(context.TODO(), bson.D{{"name", "Alice"}})
if err != nil {
log.Fatal(err)
}
Please refer to following documentation:
https://pkg.go.dev/go.mongodb.org/mongo-driver#v1.3.4/mongo?tab=doc#Collection.InsertOne

Find all documents in a collection with mongo go driver

I checked out the answer here but this uses the old and unmaintained mgo. How can I find all documents in a collection using the mongo-go-driver?
I tried passing a nil filter, but this does not return any documents and instead returns nil. I also checked the documentation but did not see any mention of returning all documents. Here is what I've tried with aforementioned result.
client, err := mongo.Connect(context.TODO(), "mongodb://localhost:27017")
coll := client.Database("test").Collection("albums")
if err != nil { fmt.Println(err) }
// we can assume we're connected...right?
fmt.Println("connected to mongodb")
var results []*Album
findOptions := options.Find()
cursor, err := coll.Find(context.TODO(), nil, findOptions)
if err != nil {
fmt.Println(err) // prints 'document is nil'
}
Also, I'm about confused about why I need to specify findOptions when I've called the Find() function on the collection (or do I not need to specify?).
Here is what I came up with using the official MongoDB driver for golang. I am using godotenv (https://github.com/joho/godotenv) to pass the database parameters.
//Find multiple documents
func FindRecords() {
err := godotenv.Load()
if err != nil {
fmt.Println(err)
}
//Get database settings from env file
//dbUser := os.Getenv("db_username")
//dbPass := os.Getenv("db_pass")
dbName := os.Getenv("db_name")
docCollection := "retailMembers"
dbHost := os.Getenv("db_host")
dbPort := os.Getenv("db_port")
dbEngine := os.Getenv("db_type")
//set client options
clientOptions := options.Client().ApplyURI("mongodb://" + dbHost + ":" + dbPort)
//connect to MongoDB
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
}
//check the connection
err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected to " + dbEngine)
db := client.Database(dbName).Collection(docCollection)
//find records
//pass these options to the Find method
findOptions := options.Find()
//Set the limit of the number of record to find
findOptions.SetLimit(5)
//Define an array in which you can store the decoded documents
var results []Member
//Passing the bson.D{{}} as the filter matches documents in the collection
cur, err := db.Find(context.TODO(), bson.D{{}}, findOptions)
if err !=nil {
log.Fatal(err)
}
//Finding multiple documents returns a cursor
//Iterate through the cursor allows us to decode documents one at a time
for cur.Next(context.TODO()) {
//Create a value into which the single document can be decoded
var elem Member
err := cur.Decode(&elem)
if err != nil {
log.Fatal(err)
}
results =append(results, elem)
}
if err := cur.Err(); err != nil {
log.Fatal(err)
}
//Close the cursor once finished
cur.Close(context.TODO())
fmt.Printf("Found multiple documents: %+v\n", results)
}
Try passing an empty bson.D instead of nil:
cursor, err := coll.Find(context.TODO(), bson.D{})
Also, FindOptions is optional.
Disclaimer: I've never used the official driver, but there are a few examples at https://godoc.org/go.mongodb.org/mongo-driver/mongo
Seems like their tutorial is outdated :/