Golang MongoDB $in Operator

MongoDB Golang Query Optimization(don't use for loop)

If you have a go struct like this:

type Student struct {
	Name string `bson:"name"`
	Age int `bson:"age"`
}

Say there are many students’ names in an array and you want to fetch the corresponding students by their names, the names are:

var names = []string{"lily", "bob", "tom"}

We want to get a students array

var students []Student

Avoid searching them in for loop one by one:

// don't do this
// time to spend is more than tens of ms, also unpredictable
for token := range tokens {
	searchOne("token", token)
}

Just using the MongoDB $in operator.

The $in operator selects the documents where the value of a field equals any value in the specified array. To specify an $in expression, use the following prototype:

{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }

The full usable code example is:

// find $in ops
func GetStudentsInValues(key string, values []string) (students []Students, err error) {
	filter := bson.M{key: bson.M{"$in": values}}
	cursor, err := db.Coll.Find(context.TODO(), filter)
	if err != nil {
		return nil, err
	}
	err = cursor.All(context.TODO(), &students)
	if err != nil {
		return nil, err
	}
	return
}

func main() {
	var students []Student
	var names = []string{"lily", "bob", "tom"}

	students, err := GetStudentsInValues("name", names)
}

In this example, if the len(students) is around 30, the bulk search spends around 20ms, the for loop search spends around 120ms.

Conclusion

Don’t use for loop send queries one by one against a DB, using bulk search.

References