使用GIN进行全文搜索时返回空列表。

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

Golang with GIN Full Text Search Returning an Empty list

问题

我正在尝试使用Golang进行全文搜索,使用Gin作为路由器和SQLC进行SQL代码生成。无论我将查询绑定为URI还是查询,我都得到一个空列表。请帮忙看看。

下面是searchProduct函数的代码:

type searchProductRequest struct {
	q        string `form:"q" binding:"required"`
	PageSize int32  `form:"page_size" binding:"required,min=1,max=10"`
}

func (server *Server) searchProduct(ctx *gin.Context) {
	var req searchProductRequest

	if err := ctx.ShouldBindQuery(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, errorResponse(err))
		return
	}

	arg := db.SearchProductParams{
		Limit:       req.PageSize,
		SearchQuery: req.q,
	}

	product, err := server.store.SearchProduct(ctx, arg)
	if err != nil {
		if err == sql.ErrNoRows {
			ctx.JSON(http.StatusNotFound, errorResponse(err))
			return
		}

		ctx.JSON(http.StatusInternalServerError, errorResponse(err))
		return
	}

	ctx.JSON(http.StatusOK, product)
}

以下是查询函数:

const searchProduct = `-- name: SearchProduct :many
SELECT id, name, owner, price, description, imgs_url, imgs_name, created_at, tsv
FROM products
WHERE textsearchable_index_col @@ to_tsquery($2)
ORDER BY created_at DESC
LIMIT $1
`

type SearchProductParams struct {
	Limit       int32  `json:"limit"`
	SearchQuery string `json:"search_query"`
}

func (q *Queries) SearchProduct(ctx context.Context, arg SearchProductParams) ([]Product, error) {
	rows, err := q.db.QueryContext(ctx, searchProduct, arg.Limit, arg.SearchQuery)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Product{}
	for rows.Next() {
		var i Product
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.Owner,
			&i.Price,
			&i.Description,
			pq.Array(&i.ImgsUrl),
			pq.Array(&i.ImgsName),
			&i.CreatedAt,
			&i.Tsv,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

当我对数据库运行原始SQL查询时,可以得到与我发送的查询相匹配的产品。以下是SQL查询:

-- name: SearchProduct :many
SELECT *
FROM products
WHERE textsearchable_index_col @@ to_tsquery(sqlc.arg(search_query))
ORDER BY created_at DESC
LIMIT $1;

我尝试将请求作为URI和表单参数在Postman中传递,但两种方法都返回一个带有空列表的200状态。请问,这个函数有什么问题?我做错了什么?这是我学习GO的第三个月。

英文:

I am trying to make a full text search using Golang with Gin as my router and SQLC for SQL code gen. I get an empty list whether i bind the Query as URI or query. PLease help.

type searchProductRequest struct {
	q        string `form:"q" binding:"required"`
	PageSize int32  `form:"page_size" binding:"required,min=1,max=10"`
}

func (server *Server) searchProduct(ctx *gin.Context) {
	var req searchProductRequest

	if err := ctx.ShouldBindQuery(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, errorResponse(err))
		return
	}

	arg := db.SearchProductParams{
		Limit:       req.PageSize,
		SearchQuery: req.q,
	}

	product, err := server.store.SearchProduct(ctx, arg)
	if err != nil {
		if err == sql.ErrNoRows {
			ctx.JSON(http.StatusNotFound, errorResponse(err))
			return
		}

		ctx.JSON(http.StatusInternalServerError, errorResponse(err))
		return
	}

	ctx.JSON(http.StatusOK, product)
}

Below is the query function:

const searchProduct = `-- name: SearchProduct :many
SELECT id, name, owner, price, description, imgs_url, imgs_name, created_at, tsv
FROM products
WHERE textsearchable_index_col @@ to_tsquery($2)
ORDER BY created_at DESC
LIMIT $1
`

type SearchProductParams struct {
	Limit       int32  `json:"limit"`
	SearchQuery string `json:"search_query"`
}

func (q *Queries) SearchProduct(ctx context.Context, arg SearchProductParams) ([]Product, error) {
	rows, err := q.db.QueryContext(ctx, searchProduct, arg.Limit, arg.SearchQuery)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Product{}
	for rows.Next() {
		var i Product
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.Owner,
			&i.Price,
			&i.Description,
			pq.Array(&i.ImgsUrl),
			pq.Array(&i.ImgsName),
			&i.CreatedAt,
			&i.Tsv,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

Running the SQL Raw Query against my db, i get the products with the query i sent.
Below is the sql query:

-- name: SearchProduct :many
SELECT *
FROM products
WHERE textsearchable_index_col @@ to_tsquery(sqlc.arg(search_query))
ORDER BY created_at DESC
LIMIT $1;

I have tried to pass the request as a URI and as form parameter in postman, but both methods still return a 200 status with an empty list. Please, what is wrong with the function? What am i doing wrong? This is my third month learning GO.

答案1

得分: 1

q,因为它以小写字母开头,是未导出的,这意味着它对于在其声明的包之外的任何代码都是不可访问的。包括反射,反射被绑定方法使用,你正在将req传递给这些方法。换句话说,将q改为Q

这是官方的语言规范相关内容:https://go.dev/ref/spec#Exported_identifiers

英文:

q, because it starts with a lower case letter, is unexported, which means it is inaccessible to any code outside of the package in which it was declared. Including reflection, which is used by the bind methods to which you are passing req. In other words, change q to Q.

And here's the official language specification on the matter: https://go.dev/ref/spec#Exported_identifiers

huangapple
  • 本文由 发表于 2022年10月12日 00:10:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/74031114.html
匿名

发表评论

匿名网友

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

确定