mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-09-18 00:41:22 -04:00
Keyword and path fields always index their case-preserved base and, when CaseInsensitive is set, an additional <field>_lowercase sibling used only for matching. The KQL lowering marks a restriction case-insensitive; each backend searches the sibling and lowercases the query value the same way the sibling is precomputed at index time (Go strings.ToLower on both sides, so non-ASCII stays consistent). Search always returns the case-preserved base, so the sibling never has to be read back. In bleve it is indexed but not stored, kept out of _all, and without doc values. In OpenSearch it deliberately stays in _source: excluding it would make every update-by-query script rebuild all siblings from the document via painless toLowerCase, which lowercases differently than Go and would drift from the query side. Keeping it in _source avoids that, and a lowercased copy of a name or path is negligible disk in a cluster. The OpenSearch move script keeps the base and its sibling in sync by swapping the moved prefix in Path_lowercase and setting Name_lowercase from Go-lowercased params, so case-insensitive search still finds a file after it moves (previously the sibling went stale). bleve re-indexes the whole document on move/delete/restore, so its siblings stay fresh for free. This also repairs OpenSearch path search (the query value was no longer folded to lowercase, so path:<Foo> returned nothing) and makes bleve path queries match a folder and its descendants like OpenSearch's path_hierarchy. The Path base stays case-preserved so the move/delete descendant update (an exact TermQuery on Path) matches mixed-case folders.
41 lines
1.5 KiB
Go
41 lines
1.5 KiB
Go
// Package mapping builds search index mappings for bleve and OpenSearch from
|
|
// a Go struct via reflection. Field names come from json tags; the caller
|
|
// provides overrides for fields that need a specific type or analyzer.
|
|
package mapping
|
|
|
|
// Field type constants used in FieldOpts.Type. An empty Type means the type
|
|
// is inferred from the Go field via reflection.
|
|
const (
|
|
TypeKeyword = "keyword"
|
|
TypeFulltext = "fulltext"
|
|
TypePath = "path"
|
|
TypeWildcard = "wildcard"
|
|
TypeNumeric = "numeric"
|
|
TypeDatetime = "datetime"
|
|
TypeBool = "bool"
|
|
TypeObject = "object"
|
|
TypeGeopoint = "geopoint"
|
|
)
|
|
|
|
// LowercaseSuffix names the lowercased sibling of a keyword/path field.
|
|
const LowercaseSuffix = "_lowercase"
|
|
|
|
// FieldOpts overrides the default type inference for a struct field. Keys in
|
|
// the override map are json-tag names (e.g. "Name", "location", "audio.artist"),
|
|
// not Go field names.
|
|
type FieldOpts struct {
|
|
// Type is one of the Type* constants. Empty means "infer from Go type".
|
|
Type string
|
|
|
|
// CaseInsensitive additionally indexes a lowercased <name>_lowercase sibling
|
|
// for case-insensitive search; the case-preserved base is always indexed.
|
|
// Nil/false means off. Keyword/path only.
|
|
CaseInsensitive *bool
|
|
|
|
// IncludeInAll controls bleve's _all field inclusion. Nil means "use the
|
|
// bleve default for this field type". Has no effect on OpenSearch.
|
|
IncludeInAll *bool
|
|
}
|
|
|
|
func (o FieldOpts) caseInsensitive() bool { return o.CaseInsensitive != nil && *o.CaseInsensitive }
|