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.