Golang中的mongoDB搜索文档

huangapple go评论69阅读模式
英文:

Golang mongoDB search document

问题

我开始学习MongoDB,并尝试通过几个参数(用户名、名字、姓氏)来搜索用户。在下面的示例中,我可以通过用户名搜索用户并获取数据。

以下示例通过多个参数进行搜索,但结果为空。

问题是,我如何通过多个参数进行搜索(使用$or)?

这个搜索选项是否最优和正确的,还是MongoDB中有更正确的搜索选项,类似于SQL中的LIKE?

谢谢您提前的回答。

英文:

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.

答案1

得分: 1

如果有人需要通过多个参数进行搜索,这可能会很有用:
我将过滤器组件放在一个单独的方法中

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 {
		// 处理空的and,因为必须有一个项目。
		return bson.M{}
	}
	return bson.M{"$and": andFilters}
}
英文:

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}
}

huangapple
  • 本文由 发表于 2022年8月29日 23:03:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/73530814.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定