Reputation: 608
I started to learn mongoDB and I'm trying to search users by a few parameters, username, firstname, lastname. In the example below I can search users by username and I get data.
// Search users
func (r *Mongo) Search(ctx context.Context, query string) ([]*User, error) {
findOptions := options.Find()
// Sort by `username` field descending
findOptions.SetSort(bson.D{{"username", -1}})
filter := bson.M{"username": bson.M{"$regex": query, "$options": "i"}}
cursor, err := r.col.Find(ctx, filter, findOptions)
if err != nil {
return nil, err
}
var results []*User
if err = cursor.All(ctx, &results); err != nil {
return nil, err
}
return results, nil
}
The following example search multiple parameters, but the result is empty.
// Search users
func (r *Mongo) Search(ctx context.Context, query string) ([]*User, error) {
findOptions := options.Find()
// Sort by `username` field descending
findOptions.SetSort(bson.D{{"username", -1}})
filter := bson.M{
"username": bson.M{"$regex": query, "$options": "i"},
"$or": []interface{}{
bson.M{"firstname": bson.M{"$regex": query, "$options": "i"}},
bson.M{"lastname": bson.M{"$regex": query, "$options": "i"}},
},
}
// filter := bson.M{"username": bson.M{"$regex": query, "$options": "i"}}
cursor, err := r.col.Find(ctx, filter, findOptions)
if err != nil {
return nil, err
}
var results []*User
if err = cursor.All(ctx, &results); err != nil {
return nil, err
}
return results, nil
}
Question, how can I search by multiple parameters(use $or)?
And Is this search option optimal and correct, or is there a more correct search option in MongoDB, analog of LIKE from SQL?
Thanks in advance for the answer.
Upvotes: 1
Views: 220
Reputation: 608
If someone needs to search by several parameters, this might be useful: I put the filter assembly in a separate method
func (r *Mongo) queryBuilderFilter(query *Query) bson.M {
var andFilters []bson.M
if query.Query != "" {
orFilters := []bson.M{
{
"username": bson.M{"$regex": primitive.Regex{Pattern: "^" + query.Query + "*", Options: "i"}},
},
{
"firstname": bson.M{"$regex": primitive.Regex{Pattern: "^" + query.Query + "*", Options: "i"}},
},
{
"lastname": bson.M{"$regex": primitive.Regex{Pattern: "^" + query.Query + "*", Options: "i"}},
},
}
andFilters = append(andFilters, bson.M{"$or": orFilters})
}
if len(andFilters) == 0 {
// Handle empty and, since there must be one item.
return bson.M{}
}
return bson.M{"$and": andFilters}
}
Upvotes: 1