go lucene
v0.0.20
用 go 编写的 lucene 解析器,没有依赖项。
使用此包,您可以快速将 lucene 样式搜索集成到您的应用程序中,并为特定查询生成 sql 过滤器。没有外部依赖,语法完全支持 Apache Lucene 9.4.2。
开箱即用的 go-lucene 支持符合 postgres 的 sql 生成,但它也可以扩展以支持不同风格的 sql(或无 sql)。
使用lucene.ToPostgres
生成一个包含所有过滤器的字符串。
使用lucene.ToParmeterizedPostgres
生成带有参数的参数化字符串,您可以将其传递给数据库查询。
使用lucene.WithDefaultField
选项将裸文字与字段关联。
// suppose you want a query for red apples that are not honey crisp or granny smith and are older than 5 months old
myQuery := `color:red AND NOT (type:"honey crisp" OR type:"granny smith") AND age_in_months:[5 TO *]`
filter , err := lucene . ToPostgres ( myQuery )
if err != nil {
// handle error
}
SQLTemplate := `
SELECT *
FROM apples
WHERE %s
LIMIT 10;
`
sqlQuery := fmt . Sprintf ( SQLTemplate , filter )
// sqlQuery is:
`
SELECT *
FROM apples
WHERE
(
("color" = 'red') AND
(
NOT(
("type" = 'honey crisp') OR
("type" = 'granny smith')
)
)
) AND
("age_in_months" >= 5)
LIMIT 10;
`
// suppose you want a query for red apples that are not honey crisp or granny smith and are older than 5 months old
myQuery := `color:red AND NOT (type:"honey crisp" OR type:"granny smith") AND age_in_months:[5 TO *]`
filter , params , err := lucene . ToParameterizedPostgres ( myQuery )
if err != nil {
// handle error
}
SQLTemplate := `
SELECT *
FROM apples
WHERE %s
LIMIT 10;
`
sqlQuery := fmt . Sprintf ( SQLTemplate , filter )
db . Query ( sqlQuery , params )
myQuery := "red OR green"
filter , err := lucene . ToPostgres (
myQuery , lucene . WithDefaultField ( "appleColor" ))
if err != nil {
// handle error
}
SQLTemplate := `
SELECT *
FROM apples
WHERE %s
LIMIT 10;
`
sqlQuery := fmt . Sprintf ( SQLTemplate , filter )
// sqlQuery is:
`
SELECT *
FROM apples
WHERE
("appleColor" = 'red') OR ("appleColor" = 'green')
LIMIT 10;
`
只需将Base
驱动程序嵌入到您的自定义驱动程序中,并使用您自己的自定义渲染函数覆盖RenderFN
即可。
import (
"github.com/grindlemire/go-lucene"
"github.com/grindlemire/go-lucene/pkg/driver"
"github.com/grindlemire/go-lucene/pkg/lucene/expr"
)
type MyDriver struct {
driver. Base
}
// Suppose we want a customer driver that is postgres but uses "==" rather than "=" for an equality check.
func NewMyDriver () MyDriver {
// register your new custom render functions. Each render function
// takes a left and optionally right rendered string and returns the rendered
// output string for the entire expression.
fns := map [expr. Operator ]driver. RenderFN {
expr . Equals : myEquals ,
}
// iterate over the existing base render functions and swap out any that you want to
for op , sharedFN := range driver . Shared {
_ , found := fns [ op ]
if ! found {
fns [ op ] = sharedFN
}
}
// return the new driver ready to use
return MyDriver {
driver. Base {
RenderFNs : fns ,
},
}
}
// Suppose we wanted to implement equals using a "==" operator instead of "="
func myEquals ( left , right string ) ( string , error ) {
return left + " == " + right , nil
}
...
func main () {
// create a new instance of the driver
driver := NewMyDriver ()
// render an expression
expr , _ := lucene . Parse ( `color:red AND NOT (type:"honey crisp" OR type:"granny smith") AND age_in_months:[5 TO *]` )
filter , _ := driver . Render ( expr )
SQLTemplate := `
SELECT *
FROM apples
WHERE %s
LIMIT 10;
`
sqlQuery := fmt . Sprintf ( SQLTemplate , filter )
// sqlQuery is:
`
SELECT *
FROM apples
WHERE
(
("color" == 'red') AND
(
NOT(
("type" == 'honey crisp') OR
("type" == 'granny smith')
)
)
) AND
("age_in_months" >= 5)
LIMIT 10;
`
}