Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL builder fro JSON_CONTAINS to search multiple values in a JSON array #139

Open
avishbran opened this issue Jun 12, 2022 · 2 comments
Open
Assignees

Comments

@avishbran
Copy link

avishbran commented Jun 12, 2022

Your Question

Is there a way to build an SQL query that searches multiple-values (not multiple keys) in a JSON array?

SELECT * FROM table WHERE JSON_CONTAINS(obj->'$.array_of_ints', [1,2,3]);

for: { "obj": {"array_of_ints":[1,2,3,4]} } the result will be TRUE.

Or:

SELECT * FROM table WHERE JSON_CONTAINS(obj->'$.array_of_ints', 2);

for: { "obj":{"array_of_ints":[1,2,3,4]} } the result will be TRUE.

The document you expected this should be explained

https://gorm.io/docs/data_types.html

Expected answer

Would like to know the methods to generate a JSON_CONTAINS SQL query using SQLBuilder

@MuhmdHsn313
Copy link

It's very important, and how we can application IN statement that in SQL with JSON query?

@itswuanran
Copy link

itswuanran commented Jul 27, 2023

Your Question

Is there a way to build an SQL query that searches multiple-values (not multiple keys) in a JSON array?

SELECT * FROM table WHERE JSON_CONTAINS(obj->'$.array_of_ints', [1,2,3]);

for: { "obj": {"array_of_ints":[1,2,3,4]} } the result will be TRUE.

Or:

SELECT * FROM table WHERE JSON_CONTAINS(obj->'$.array_of_ints', 2);

for: { "obj":{"array_of_ints":[1,2,3,4]} } the result will be TRUE.

The document you expected this should be explained

https://gorm.io/docs/data_types.html

Expected answer

Would like to know the methods to generate a JSON_CONTAINS SQL query using SQLBuilder

// Build implements clause.Expression
func (json *JSONArrayExpression) Build(builder clause.Builder) {
	if stmt, ok := builder.(*gorm.Statement); ok {
		switch stmt.Dialector.Name() {
		case "mysql":
			builder.WriteString("JSON_CONTAINS (" + stmt.Quote(json.column) + ", JSON_ARRAY(")
			builder.AddVar(stmt, json.equalsValue)
			builder.WriteString("))")
		}
	}
}

datatypes.JSONArrayExpression append a JSON_ARRAY('') string in Build method, and this does not support slice value, I finally found a solution to this problem.

package cdatatypes

import (
	"gorm.io/gen/field"
	"gorm.io/gorm/clause"
)

type ExprCond struct {
	clause.Expr
	field.String
}

func Cond(expr clause.Expr) *ExprCond {
	return &ExprCond{
		Expr:   expr,
		String: field.String{},
	}
}

func (c *ExprCond) BeCond() interface{} { return c.Expr }

func (c *ExprCond) CondError() error { return nil }

Then use the code to support custom conditions. And this cond implements gen.Condition interface

cdatatypes.Cond(gorm.Expr("JSON_CONTAINS (`tag`, ?)", tags))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants