sqlxb

package module
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2025 License: Apache-2.0 Imports: 8 Imported by: 0

README

sqlxb

OSCS Status workflow build GitHub tag Go Report Card

AI-First SQL Builder for Relational and Vector Databases

a tool of sql query builder, build sql for sql.DB, sqlx, gorp, or build condition sql for some orm framework, like xorm, gorm....


🚀 NEW: Vector Database Support (v0.9.0)

The first unified ORM for both Relational and Vector Databases!

✨ New in v0.9.0:

  • 🎯 Vector Diversity Queries - 3 strategies to solve result similarity
  • 🔄 Qdrant JSON Generation - Native Qdrant support
  • 🎨 Graceful Degradation - Same code, multiple backends
  • 🔧 9-Layer Auto Filtering - Zero manual checks
// MySQL (existing)
sqlxb.Of(&Order{}).Eq("status", 1).Build().SqlOfSelect()

// VectorDB (coming soon) - Same API!
sqlxb.Of(&CodeVector{}).
    Eq("language", "golang").
    VectorSearch("embedding", queryVector, 10).
    Build().SqlOfVectorSearch()

📖 Read the Vector Database Design Docs →

Features:

  • ✅ Unified API for MySQL + VectorDB
  • ✅ Type-safe ORM for vectors
  • ✅ Auto-optimized hybrid queries
  • ✅ 100% backward compatible

Development: AI-First approach (Claude AI + Human review)


🤖 AI-First Development

sqlxb v0.8.0+ is developed using an innovative AI-First approach:

  • 🤖 AI Assistant (Claude via Cursor): Architecture design, code implementation, testing, documentation
  • 👨‍💻 Human Maintainer: Code review, strategic decisions, critical algorithm oversight
Maintenance Model (80/15/5)
  • 80% of code: AI independently maintains (simple, clear patterns)
  • 15% of code: AI assists, human reviews (medium complexity)
  • 5% of code: Human leads, AI assists (critical algorithms like from_builder_optimization.go)
v0.8.1 Vector Database Support

Achieved entirely through AI-First development:

  • Architecture & Design: AI Assistant (Claude)
  • Code Implementation: AI Assistant (763 lines)
  • Testing: AI Assistant (13 test cases, 100% passing)
  • Documentation: AI Assistant (120+ pages)
  • Review & Approval: Human Maintainer

This makes sqlxb one of the first major Go ORM projects successfully maintained by AI.


Program feature:

  • ignore building nil or empty string

Available field of struct:

  • base: string, *bool, *int64, *float64, time.Time....
  • json: struct, map, array, slice
  • bytes: []byte

Example

SELECT * FROM t_cat WHERE id > ? AND (price >= ? OR is_sold = ?)

var Db *sqlx.DB
....

var c Cat
builder := sqlxb.Of(&c).Gt("id", 10000).And(func(cb *CondBuilder) {
	cb.Gte("price", catRo.Price).OR().Eq("is_sold", catRo.IsSold))
})

countSql, dataSql, vs, _ := builder.Build().SqlOfPage()
var catList []Cat
err = Db.Select(&catList, dataSql, vs...)

Contributing

Contributors are welcomed to join the sqlxb project.
Please check CONTRIBUTING

Quickstart

Single Example

import (
    . "github.com/x-ream/sqlxb"
)

type Cat struct {
	Id       uint64    `db:"id"`
	Name     string    `db:"name"`
	Age      uint      `db:"age"`
	Color    string    `db:"color"`
	Weight   float64   `db:"weight"`
	IsSold   *bool     `db:"is_sold"`
	Price    *float64  `db:"price"`
	CreateAt time.Time `db:"create_at"`
}

func (*Cat) TableName() string {
	return "t_cat"
}

// IsSold, Price, fields can be zero, must be pointer, like Java Boolean....
// sqlxb has func: Bool(true), Int(v) ....
// sqlxb no relect, not support omitempty, should rewrite ro, dto
type CatRo struct {
	Name   string   `json:"name, string"`
	IsSold *bool    `json:"isSold, *bool"`
	Price  *float64 `json:"price, *float64"`
	Age    uint     `json:"age", unit`
}

func main() {
	cat := Cat{
		Id:       100002,
		Name:     "Tuanzi",
		Age:      1,
		Color:    "B",
		Weight:   8.5,
		IsSold:   Bool(true),
		Price:    Float64(10000.00),
		CreateAt: time.Now(),
	}
    // INSERT .....

    // PREPARE TO QUERY
	catRo := CatRo{
		Name:	"Tu",
		IsSold: nil,
		Price:  Float64(5000.00),
		Age:    1,
	}

	preCondition := func() bool {
		if cat.Color == "W" {
			return true
		} else if cat.Weight <= 3 {
			return false
		} else {
			return true
		}
	}

	var c Cat
	var builder = Of(&c)
	builder.LikeLeft("name",catRo.Name)
	builder.X("weight <> ?", 0) //X(k, v...), hardcode func, value 0 and nil will NOT ignore
    //Eq,Ne,Gt.... value 0 and nil will ignore, like as follow: OR().Eq("is_sold", catRo.IsSold)
	builder.And(func(cb *CondBuilder) {
            cb.Gte("price", catRo.Price).OR().Gte("age", catRo.Age).OR().Eq("is_sold", catRo.IsSold))
	    })
    //func Bool NOT designed for value nil or 0; designed to convert complex logic to bool
    //Decorator pattern suggest to use func Bool preCondition, like:
    //myBoolDecorator := NewMyBoolDecorator(para)
    //builder.Bool(myBoolDecorator.fooCondition, func(cb *CondBuilder) {
	builder.Bool(preCondition, func(cb *CondBuilder) {
            cb.Or(func(cb *CondBuilder) {
                cb.Lt("price", 5000)
            })
	})
	builder.Sort("id", ASC)
        builder.Paged(func(pb *PageBuilder) {
                pb.Page(1).Rows(10).IgnoreTotalRows()
            })
    countSql, dataSql, vs, _ := builder.Build().SqlOfPage()
    // ....

    //dataSql: SELECT * FROM t_cat WHERE id > ? AND name LIKE ? AND weight <> 0 AND (price >= ? OR age >= ?) OR (price < ?)
    //ORDER BY id ASC LIMIT 10

	//.IgnoreTotalRows(), will not output countSql
    //countSql: SELECT COUNT(*) FROM t_cat WHERE name LIKE ? AND weight <> 0 AND (price >= ? OR age >= ?) OR (price < ?)
    
    //sqlx: 	err = Db.Select(&catList, dataSql,vs...)
	joinSql, condSql, cvs := builder.Build().SqlOfCond()
    
    //conditionSql: id > ? AND name LIKE ? AND weight <> 0 AND (price >= ? OR age >= ?) OR (price < ?)

}
Join Example
import (
        . "github.com/x-ream/sqlxb"
    )
    
func main() {
	
	sub := func(sb *BuilderX) {
                sb.Select("id","type").From("t_pet").Gt("id", 10000) //....
            }
	
        builder := X().
		Select("p.id","p.weight").
		FromX(func(fb *FromBuilder) {
                    fb.
                        Sub(sub).As("p").
                        JOIN(INNER).Of("t_dog").As("d").On("d.pet_id = p.id").
                        JOIN(LEFT).Of("t_cat").As("c").On("c.pet_id = p.id").
                            Cond(func(on *ON) {
                                on.Gt("c.id", ro.MinCatId)
                            })
		    }).
	        Ne("p.type","PIG").
                Having(func(cb *CondBuilderX) {
                    cb.Sub("p.weight > ?", func(sb *BuilderX) {
                        sb.Select("AVG(weight)").From("t_dog")
                    })
                })
    
}


Documentation

Overview

Copyright 2020 io.xream.sqlxb

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Index

Constants

View Source
const (
	XX       = ""
	AGG      = ""
	SUB      = "SUB"
	AND      = "AND"
	OR       = "OR"
	AND_SUB  = AND
	OR_SUB   = OR
	EQ       = "="
	NE       = "<>"
	GT       = ">"
	LT       = "<"
	GTE      = ">="
	LTE      = "<="
	LIKE     = "LIKE"
	NOT_LIKE = "NOT LIKE"
	IN       = "IN"
	NIN      = "NOT IN"
	IS_NULL  = "IS NULL"
	NON_NULL = "IS NOT NULL"
)
View Source
const (
	VECTOR_SEARCH          = "VECTOR_SEARCH"
	VECTOR_DISTANCE_FILTER = "VECTOR_DISTANCE_FILTER"
)

向量操作符(v0.8.0 新增)

Variables

This section is empty.

Functions

func ASC

func ASC() string

func ASOF added in v0.5.4

func ASOF() string

func Bool

func Bool(b bool) *bool

func Byte

func Byte(b byte) *byte

func CROSS added in v0.5.4

func CROSS() string

func DESC

func DESC() string

func Eq

func Eq() string

func FULL_OUTER added in v0.5.4

func FULL_OUTER() string

func Float32

func Float32(f float32) *float32

func Float64

func Float64(f float64) *float64

func GLOBAL added in v0.5.4

func GLOBAL() string

func Gt

func Gt() string

func Gte

func Gte() string

func INNER added in v0.5.4

func INNER() string

func Int

func Int(v int) *int

func Int8

func Int8(v int8) *int8

func Int16

func Int16(v int16) *int16

func Int32

func Int32(v int32) *int32

func Int64

func Int64(v int64) *int64

func IsNull

func IsNull() string

func LEFT added in v0.5.4

func LEFT() string

func Like

func Like() string

func LikeLeft added in v0.5.9

func LikeLeft() string

func Lt

func Lt() string

func Lte

func Lte() string

func N2s

func N2s(p interface{}) string

func NON_JOIN added in v0.5.4

func NON_JOIN() string

func Ne

func Ne() string

func NilOrNumber

func NilOrNumber(p interface{}) (bool, interface{})

func NonNull

func NonNull() string

func NotLike

func NotLike() string

func Np2s

func Np2s(p interface{}) (string, bool)

func QdrantDistanceMetric added in v0.9.0

func QdrantDistanceMetric(metric VectorDistance) string

QdrantDistanceMetric 转换距离度量

func RIGHT() string

func Uint

func Uint(v uint) *uint

func Uint64

func Uint64(v uint64) *uint64

Types

type Bb

type Bb struct {
	// contains filtered or unexported fields
}

type BoolFunc

type BoolFunc func() bool

type BuilderX

type BuilderX struct {
	CondBuilderX
	// contains filtered or unexported fields
}

ToId build sql, like: SELECT DISTINCT f.id FROM foo f INNER_JOIN JOIN (SELECT foo_id FROM bar) b ON b.foo_id = f.id Sql for MySQL, Clickhouse....

@author Sim

func Of added in v0.5.5

func Of(tableNameOrPo interface{}) *BuilderX

func X

func X() *BuilderX

func (*BuilderX) Agg added in v0.4.0

func (x *BuilderX) Agg(fn string, vs ...interface{}) *BuilderX

func (*BuilderX) And added in v0.5.5

func (x *BuilderX) And(f func(cb *CondBuilder)) *BuilderX

func (*BuilderX) Any added in v0.5.12

func (x *BuilderX) Any(f func(x *BuilderX)) *BuilderX

func (*BuilderX) As added in v0.5.9

func (x *BuilderX) As(alia string) *BuilderX

func (*BuilderX) Bool added in v0.5.5

func (x *BuilderX) Bool(preCond BoolFunc, then func(cb *CondBuilder)) *BuilderX

func (*BuilderX) Build

func (x *BuilderX) Build() *Built

func (*BuilderX) Eq added in v0.5.5

func (x *BuilderX) Eq(k string, v interface{}) *BuilderX

func (*BuilderX) From added in v0.5.7

func (x *BuilderX) From(orFromSql string) *BuilderX

func (*BuilderX) FromX added in v0.5.7

func (x *BuilderX) FromX(f func(fb *FromBuilder)) *BuilderX

func (*BuilderX) GroupBy

func (x *BuilderX) GroupBy(groupBy string) *BuilderX

func (*BuilderX) Gt added in v0.5.5

func (x *BuilderX) Gt(k string, v interface{}) *BuilderX

func (*BuilderX) Gte added in v0.5.5

func (x *BuilderX) Gte(k string, v interface{}) *BuilderX

func (*BuilderX) Having

func (x *BuilderX) Having(f func(cb *CondBuilderX)) *BuilderX

func (*BuilderX) In added in v0.5.5

func (x *BuilderX) In(k string, vs ...interface{}) *BuilderX

func (*BuilderX) Insert added in v0.7.0

func (x *BuilderX) Insert(f func(b *InsertBuilder)) *BuilderX

func (*BuilderX) IsNull added in v0.5.5

func (x *BuilderX) IsNull(key string) *BuilderX

func (*BuilderX) Last added in v0.5.13

func (x *BuilderX) Last(last string) *BuilderX

func (*BuilderX) Like added in v0.5.5

func (x *BuilderX) Like(k string, v string) *BuilderX

func (*BuilderX) LikeLeft added in v0.5.9

func (x *BuilderX) LikeLeft(k string, v string) *BuilderX

func (*BuilderX) Lt added in v0.5.5

func (x *BuilderX) Lt(k string, v interface{}) *BuilderX

func (*BuilderX) Lte added in v0.5.5

func (x *BuilderX) Lte(k string, v interface{}) *BuilderX

func (*BuilderX) Ne added in v0.5.5

func (x *BuilderX) Ne(k string, v interface{}) *BuilderX

func (*BuilderX) Nin added in v0.5.5

func (x *BuilderX) Nin(k string, vs ...interface{}) *BuilderX

func (*BuilderX) NonNull added in v0.5.5

func (x *BuilderX) NonNull(key string) *BuilderX

func (*BuilderX) NotLike added in v0.5.5

func (x *BuilderX) NotLike(k string, v string) *BuilderX

func (*BuilderX) OR added in v0.5.5

func (x *BuilderX) OR() *BuilderX

func (*BuilderX) Or added in v0.5.5

func (x *BuilderX) Or(f func(cb *CondBuilder)) *BuilderX

func (*BuilderX) Paged added in v0.5.5

func (x *BuilderX) Paged(f func(pb *PageBuilder)) *BuilderX

func (*BuilderX) Select added in v0.5.6

func (x *BuilderX) Select(resultKeys ...string) *BuilderX

func (*BuilderX) Sort added in v0.5.5

func (x *BuilderX) Sort(orderBy string, direction Direction) *BuilderX

func (*BuilderX) Sub added in v0.5.3

func (x *BuilderX) Sub(s string, f func(sb *BuilderX)) *BuilderX

func (*BuilderX) Update added in v0.6.0

func (x *BuilderX) Update(f func(ub *UpdateBuilder)) *BuilderX

func (*BuilderX) VectorDistance added in v0.8.1

func (x *BuilderX) VectorDistance(metric VectorDistance) *BuilderX

VectorDistance 设置向量距离度量(BuilderX 扩展)

示例:

builder.VectorSearch("embedding", vec, 10).
    VectorDistance(sqlxb.L2Distance)

func (*BuilderX) VectorDistanceFilter added in v0.8.1

func (x *BuilderX) VectorDistanceFilter(
	field string,
	queryVector Vector,
	op string,
	threshold float32,
) *BuilderX

VectorDistanceFilter 向量距离过滤(BuilderX 扩展)

示例:

builder.VectorDistanceFilter("embedding", queryVector, "<", 0.3)

func (*BuilderX) VectorSearch added in v0.8.1

func (x *BuilderX) VectorSearch(field string, queryVector Vector, topK int) *BuilderX

VectorSearch 向量相似度检索(BuilderX 扩展) 与 CondBuilder.VectorSearch() 功能相同,但返回 *BuilderX 用于链式调用

示例:

sqlxb.Of(&CodeVector{}).
    Eq("language", "golang").
    VectorSearch("embedding", queryVector, 10).
    Build().
    SqlOfVectorSearch()

func (*BuilderX) WithDiversity added in v0.9.0

func (x *BuilderX) WithDiversity(strategy DiversityStrategy, params ...interface{}) *BuilderX

WithDiversity 设置多样性参数(BuilderX 扩展) ⭐ 核心:如果数据库不支持,会被自动忽略

示例:

sqlxb.Of(&CodeVector{}).
    VectorSearch("embedding", vec, 20).
    WithDiversity(sqlxb.DiversityByHash, "semantic_hash").
    Build()

func (*BuilderX) WithHashDiversity added in v0.9.0

func (x *BuilderX) WithHashDiversity(hashField string) *BuilderX

WithHashDiversity 设置哈希去重(BuilderX 扩展)

示例:

sqlxb.Of(&CodeVector{}).
    VectorSearch("embedding", vec, 20).
    WithHashDiversity("semantic_hash").
    Build()

func (*BuilderX) WithMMR added in v0.9.0

func (x *BuilderX) WithMMR(lambda float32) *BuilderX

WithMMR 设置 MMR 算法(BuilderX 扩展)

示例:

sqlxb.Of(&CodeVector{}).
    VectorSearch("embedding", vec, 20).
    WithMMR(0.5).
    Build()

func (*BuilderX) WithMinDistance added in v0.9.0

func (x *BuilderX) WithMinDistance(minDistance float32) *BuilderX

WithMinDistance 设置最小距离多样性(BuilderX 扩展)

示例:

sqlxb.Of(&CodeVector{}).
    VectorSearch("embedding", vec, 20).
    WithMinDistance(0.3).
    Build()

func (*BuilderX) WithoutOptimization

func (x *BuilderX) WithoutOptimization() *BuilderX

func (*BuilderX) X added in v0.5.5

func (x *BuilderX) X(k string, vs ...interface{}) *BuilderX

type Built

type Built struct {
	Delete     bool
	Inserts    *[]Bb
	Updates    *[]Bb
	ResultKeys []string
	Conds      []Bb
	Sorts      []Sort
	Havings    []Bb
	GroupBys   []string
	Aggs       []Bb
	Last       string
	OrFromSql  string
	Fxs        []*FromX
	Svs        []interface{}

	PageCondition *PageCondition
}

func (*Built) SqlOfCond added in v0.5.8

func (built *Built) SqlOfCond() (string, string, []interface{})

func (*Built) SqlOfDelete added in v0.7.1

func (built *Built) SqlOfDelete() (string, []interface{})

func (*Built) SqlOfInsert added in v0.7.0

func (built *Built) SqlOfInsert() (string, []interface{})

func (*Built) SqlOfPage added in v0.6.1

func (built *Built) SqlOfPage() (string, string, []interface{}, map[string]string)

func (*Built) SqlOfSelect added in v0.6.1

func (built *Built) SqlOfSelect() (string, []interface{}, map[string]string)

func (*Built) SqlOfUpdate added in v0.6.0

func (built *Built) SqlOfUpdate() (string, []interface{})

func (*Built) SqlOfVectorSearch added in v0.8.1

func (built *Built) SqlOfVectorSearch() (string, []interface{})

SqlOfVectorSearch 生成向量检索 SQL 返回: sql, args

示例输出:

SELECT *, embedding <-> ? AS distance
FROM code_vectors
WHERE language = ?
ORDER BY distance
LIMIT 10

func (*Built) ToQdrantJSON added in v0.9.0

func (built *Built) ToQdrantJSON() (string, error)

ToQdrantJSON 转换为 Qdrant 搜索 JSON 返回: JSON 字符串, error

示例输出:

{
  "vector": [0.1, 0.2, 0.3],
  "limit": 20,
  "filter": {
    "must": [
      {"key": "language", "match": {"value": "golang"}}
    ]
  },
  "with_payload": true,
  "params": {"hnsw_ef": 128}
}

func (*Built) ToQdrantRequest added in v0.9.0

func (built *Built) ToQdrantRequest() (*QdrantSearchRequest, error)

ToQdrantRequest 转换为 Qdrant 请求结构

type CondBuilder added in v0.5.1

type CondBuilder struct {
	// contains filtered or unexported fields
}

func (*CondBuilder) And added in v0.5.1

func (cb *CondBuilder) And(f func(cb *CondBuilder)) *CondBuilder

func (*CondBuilder) Bool added in v0.5.1

func (cb *CondBuilder) Bool(preCond BoolFunc, f func(cb *CondBuilder)) *CondBuilder

func (*CondBuilder) Eq added in v0.5.1

func (cb *CondBuilder) Eq(k string, v interface{}) *CondBuilder

func (*CondBuilder) Gt added in v0.5.1

func (cb *CondBuilder) Gt(k string, v interface{}) *CondBuilder

func (*CondBuilder) Gte added in v0.5.1

func (cb *CondBuilder) Gte(k string, v interface{}) *CondBuilder

func (*CondBuilder) In added in v0.5.1

func (cb *CondBuilder) In(k string, vs ...interface{}) *CondBuilder

func (*CondBuilder) IsNull added in v0.5.1

func (cb *CondBuilder) IsNull(key string) *CondBuilder

func (*CondBuilder) Like added in v0.5.1

func (cb *CondBuilder) Like(k string, v string) *CondBuilder

Like sql: LIKE %value%, Like() default has double %

func (*CondBuilder) LikeLeft added in v0.5.9

func (cb *CondBuilder) LikeLeft(k string, v string) *CondBuilder

LikeLeft sql: LIKE value%, Like() default has double %, then LikeLeft() remove left %

func (*CondBuilder) Lt added in v0.5.1

func (cb *CondBuilder) Lt(k string, v interface{}) *CondBuilder

func (*CondBuilder) Lte added in v0.5.1

func (cb *CondBuilder) Lte(k string, v interface{}) *CondBuilder

func (*CondBuilder) Ne added in v0.5.1

func (cb *CondBuilder) Ne(k string, v interface{}) *CondBuilder

func (*CondBuilder) Nin added in v0.5.1

func (cb *CondBuilder) Nin(k string, vs ...interface{}) *CondBuilder

func (*CondBuilder) NonNull added in v0.5.1

func (cb *CondBuilder) NonNull(key string) *CondBuilder

func (*CondBuilder) NotLike added in v0.5.1

func (cb *CondBuilder) NotLike(k string, v string) *CondBuilder

func (*CondBuilder) OR added in v0.5.1

func (cb *CondBuilder) OR() *CondBuilder

func (*CondBuilder) Or added in v0.5.1

func (cb *CondBuilder) Or(f func(cb *CondBuilder)) *CondBuilder

func (*CondBuilder) VectorDistance added in v0.8.1

func (cb *CondBuilder) VectorDistance(metric VectorDistance) *CondBuilder

VectorDistance 设置向量距离度量 必须在 VectorSearch() 之后调用

示例:

builder.VectorSearch("embedding", vec, 10).VectorDistance(sqlxb.L2Distance)

func (*CondBuilder) VectorDistanceFilter added in v0.8.1

func (cb *CondBuilder) VectorDistanceFilter(
	field string,
	queryVector Vector,
	op string,
	threshold float32,
) *CondBuilder

VectorDistanceFilter 向量距离过滤 用于: WHERE distance < threshold

示例:

builder.VectorDistanceFilter("embedding", queryVector, "<", 0.3)

生成 SQL:

WHERE (embedding <-> $1) < 0.3

func (*CondBuilder) VectorSearch added in v0.8.1

func (cb *CondBuilder) VectorSearch(field string, queryVector Vector, topK int) *CondBuilder

VectorSearch 向量相似度检索 field: 向量字段名 queryVector: 查询向量 topK: 返回 Top-K 个最相似的结果

示例:

builder.VectorSearch("embedding", queryVector, 10)

生成 SQL:

ORDER BY embedding <-> $1 LIMIT 10

func (*CondBuilder) WithDiversity added in v0.9.0

func (cb *CondBuilder) WithDiversity(strategy DiversityStrategy, params ...interface{}) *CondBuilder

WithDiversity 链式设置多样性参数 ⭐ 核心:如果数据库不支持,会被自动忽略

示例:

builder.VectorSearch("embedding", vec, 20).
    WithDiversity(sqlxb.DiversityByHash, "semantic_hash")

func (*CondBuilder) WithHashDiversity added in v0.9.0

func (cb *CondBuilder) WithHashDiversity(hashField string) *CondBuilder

WithHashDiversity 快捷方法:设置哈希去重

示例:

builder.VectorSearch("embedding", vec, 20).
    WithHashDiversity("semantic_hash")

func (*CondBuilder) WithMMR added in v0.9.0

func (cb *CondBuilder) WithMMR(lambda float32) *CondBuilder

WithMMR 快捷方法:设置 MMR 算法

示例:

builder.VectorSearch("embedding", vec, 20).
    WithMMR(0.5)  // lambda = 0.5,平衡相关性和多样性

func (*CondBuilder) WithMinDistance added in v0.9.0

func (cb *CondBuilder) WithMinDistance(minDistance float32) *CondBuilder

WithMinDistance 快捷方法:设置最小距离多样性

示例:

builder.VectorSearch("embedding", vec, 20).
    WithMinDistance(0.3)

func (*CondBuilder) X added in v0.5.1

func (cb *CondBuilder) X(k string, vs ...interface{}) *CondBuilder

type CondBuilderX added in v0.5.11

type CondBuilderX struct {
	CondBuilder
}

func (*CondBuilderX) Sub added in v0.5.11

func (x *CondBuilderX) Sub(s string, f func(sb *BuilderX)) *CondBuilderX

type Direction

type Direction func() string

type DiversityParams added in v0.9.0

type DiversityParams struct {
	// Enabled 是否启用多样性
	Enabled bool

	// Strategy 多样性策略
	Strategy DiversityStrategy

	// HashField 语义哈希字段名(用于 DiversityByHash)
	// 例如: "semantic_hash", "content_hash"
	HashField string

	// MinDistance 结果之间的最小距离(用于 DiversityByDistance)
	// 例如: 0.3 表示结果之间的距离至少为 0.3
	MinDistance float32

	// Lambda MMR 平衡参数(用于 DiversityByMMR)
	// 范围: 0-1
	// 0 = 完全多样性
	// 1 = 完全相关性
	// 0.5 = 平衡(推荐)
	Lambda float32

	// OverFetchFactor 过度获取因子
	// 先获取 TopK * OverFetchFactor 个结果,再应用多样性过滤
	// 默认: 5(获取 5 倍的结果后过滤)
	OverFetchFactor int
}

DiversityParams 多样性查询参数

type DiversityStrategy added in v0.9.0

type DiversityStrategy string

DiversityStrategy 多样性策略

const (
	// DiversityByHash 基于语义哈希去重
	DiversityByHash DiversityStrategy = "hash"

	// DiversityByDistance 基于向量距离去重
	DiversityByDistance DiversityStrategy = "distance"

	// DiversityByMMR 使用 MMR(Maximal Marginal Relevance)算法
	DiversityByMMR DiversityStrategy = "mmr"
)

type FromBuilder added in v0.5.6

type FromBuilder struct {
	// contains filtered or unexported fields
}

func (*FromBuilder) As added in v0.5.9

func (fb *FromBuilder) As(alia string) *FromBuilder

func (*FromBuilder) Cond added in v0.5.6

func (fb *FromBuilder) Cond(on func(on *ON)) *FromBuilder

func (*FromBuilder) JOIN added in v0.5.6

func (fb *FromBuilder) JOIN(join JOIN) *FromBuilder

func (*FromBuilder) Of added in v0.5.6

func (fb *FromBuilder) Of(tableName string) *FromBuilder

func (*FromBuilder) On added in v0.5.6

func (fb *FromBuilder) On(onStr string) *FromBuilder

func (*FromBuilder) Sub added in v0.5.6

func (fb *FromBuilder) Sub(sub func(sb *BuilderX)) *FromBuilder

func (*FromBuilder) Using added in v0.5.6

func (fb *FromBuilder) Using(key string) *FromBuilder

type FromX added in v0.5.6

type FromX struct {
	// contains filtered or unexported fields
}

type InsertBuilder added in v0.7.0

type InsertBuilder struct {
	// contains filtered or unexported fields
}

func (*InsertBuilder) Set added in v0.7.0

func (b *InsertBuilder) Set(k string, v interface{}) *InsertBuilder

type JOIN

type JOIN func() string

*

  • Config your own JOIN string as string func

type Join

type Join struct {
	// contains filtered or unexported fields
}

type LongId

type LongId interface {
	GetId() uint64
}

type ON

type ON struct {
	CondBuilder
	// contains filtered or unexported fields
}

type Op

type Op func() string

type PageBuilder

type PageBuilder struct {
	// contains filtered or unexported fields
}

func (*PageBuilder) IgnoreTotalRows

func (pb *PageBuilder) IgnoreTotalRows() *PageBuilder

func (*PageBuilder) Last

func (pb *PageBuilder) Last(last uint64) *PageBuilder

Last if ASC: orderBy > last else DESC: orderBy < last LIMIT rows

func (*PageBuilder) Page

func (pb *PageBuilder) Page(page uint) *PageBuilder

func (*PageBuilder) Rows

func (pb *PageBuilder) Rows(rows uint) *PageBuilder

func (*PageBuilder) SetTotalRowsIgnored added in v0.5.1

func (pb *PageBuilder) SetTotalRowsIgnored(ignored bool) *PageBuilder

type PageCondition

type PageCondition struct {
	// contains filtered or unexported fields
}

type Po

type Po interface {
	TableName() string
}

type QdrantCondition added in v0.9.0

type QdrantCondition struct {
	Key   string                `json:"key,omitempty"`
	Match *QdrantMatchCondition `json:"match,omitempty"`
	Range *QdrantRangeCondition `json:"range,omitempty"`
}

QdrantCondition Qdrant 条件

type QdrantFilter added in v0.9.0

type QdrantFilter struct {
	Must    []QdrantCondition `json:"must,omitempty"`
	Should  []QdrantCondition `json:"should,omitempty"`
	MustNot []QdrantCondition `json:"must_not,omitempty"`
}

QdrantFilter Qdrant 过滤器

type QdrantMatchCondition added in v0.9.0

type QdrantMatchCondition struct {
	Value interface{}   `json:"value,omitempty"`
	Any   []interface{} `json:"any,omitempty"`
}

QdrantMatchCondition Qdrant 精确匹配条件

type QdrantRangeCondition added in v0.9.0

type QdrantRangeCondition struct {
	Gt  *float64 `json:"gt,omitempty"`
	Gte *float64 `json:"gte,omitempty"`
	Lt  *float64 `json:"lt,omitempty"`
	Lte *float64 `json:"lte,omitempty"`
}

QdrantRangeCondition Qdrant 范围条件

type QdrantSearchParams added in v0.9.0

type QdrantSearchParams struct {
	HnswEf      int  `json:"hnsw_ef,omitempty"`
	Exact       bool `json:"exact,omitempty"`
	IndexedOnly bool `json:"indexed_only,omitempty"`
}

QdrantSearchParams Qdrant 搜索参数

type QdrantSearchRequest added in v0.9.0

type QdrantSearchRequest struct {
	Vector         []float32           `json:"vector"`
	Limit          int                 `json:"limit"`
	Filter         *QdrantFilter       `json:"filter,omitempty"`
	WithPayload    interface{}         `json:"with_payload,omitempty"` // true, false, or []string
	WithVector     bool                `json:"with_vector,omitempty"`
	ScoreThreshold *float32            `json:"score_threshold,omitempty"`
	Offset         int                 `json:"offset,omitempty"`
	Params         *QdrantSearchParams `json:"params,omitempty"`
}

QdrantSearchRequest Qdrant 搜索请求结构 文档: https://qdrant.tech/documentation/concepts/search/

type Sort

type Sort struct {
	// contains filtered or unexported fields
}

type StringId

type StringId interface {
	GetId() string
}

type TotalRows added in v0.5.13

type TotalRows struct {
	Count int64 `db:"COUNT(*)"`
}

type USING added in v0.4.0

type USING struct {
	// contains filtered or unexported fields
}

type UpdateBuilder added in v0.6.0

type UpdateBuilder struct {
	// contains filtered or unexported fields
}

func (*UpdateBuilder) Any added in v0.6.0

func (ub *UpdateBuilder) Any(f func(*UpdateBuilder)) *UpdateBuilder

func (*UpdateBuilder) Bool added in v0.6.0

func (ub *UpdateBuilder) Bool(preCond BoolFunc, f func(cb *UpdateBuilder)) *UpdateBuilder

func (*UpdateBuilder) Set added in v0.6.0

func (ub *UpdateBuilder) Set(k string, v interface{}) *UpdateBuilder

func (*UpdateBuilder) X added in v0.6.0

func (ub *UpdateBuilder) X(s string, vs ...interface{}) *UpdateBuilder

type Vector added in v0.8.1

type Vector []float32

Vector 向量类型(兼容 PostgreSQL pgvector)

func (Vector) Dim added in v0.8.1

func (v Vector) Dim() int

Dim 返回向量维度

func (Vector) Distance added in v0.8.1

func (v Vector) Distance(other Vector, metric VectorDistance) float32

Distance 计算两个向量的距离

func (Vector) Normalize added in v0.8.1

func (v Vector) Normalize() Vector

Normalize 向量归一化(L2范数)

func (*Vector) Scan added in v0.8.1

func (v *Vector) Scan(value interface{}) error

Scan 实现 sql.Scanner 接口

func (Vector) Value added in v0.8.1

func (v Vector) Value() (driver.Value, error)

Value 实现 driver.Valuer 接口

type VectorDistance added in v0.8.1

type VectorDistance string

VectorDistance 向量距离度量类型

const (
	// CosineDistance 余弦距离(最常用)
	// PostgreSQL: <->
	CosineDistance VectorDistance = "<->"

	// L2Distance 欧氏距离(L2范数)
	// PostgreSQL: <#>
	L2Distance VectorDistance = "<#>"

	// InnerProduct 内积距离(点积)
	// PostgreSQL: <=>
	InnerProduct VectorDistance = "<=>"
)

type VectorDistanceFilterParams added in v0.8.1

type VectorDistanceFilterParams struct {
	QueryVector    Vector
	Operator       string // <, <=, >, >=, =
	Threshold      float32
	DistanceMetric VectorDistance
}

VectorDistanceFilterParams 向量距离过滤参数

type VectorSearchParams added in v0.8.1

type VectorSearchParams struct {
	QueryVector    Vector
	TopK           int
	DistanceMetric VectorDistance
	Diversity      *DiversityParams // ⭐ 新增:多样性参数(可选)
}

VectorSearchParams 向量检索参数

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL