mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-25 00:46:37 -04:00
fix(search): preserve value case for non-lowercased bleve fields
The bleve compiler lowercased every query value (except Hidden) before handing it to the engine. This matched the index tokens for fields whose analyzer folds case — Name, Tags, Favorites, Content — but silently broke matching for every other field, whose default keyword analyzer preserves case. A query like Title:"Some Title" parsed fine, lowercased to "some title", and missed the indexed token "Some Title". Replace the blanket lowercasing with an allowlist of the four fields whose index mapping actually uses a lowercasing analyzer. Every other field now passes through unchanged, which keeps values like "deadmau5" or "Motörhead" intact instead of normalising them to a case the tag writer didn't choose.
This commit is contained in:
@@ -137,6 +137,18 @@ var _ = Describe("Bleve", func() {
|
||||
assertDocCount(rootResource.ID, "Size:<1000", 0)
|
||||
assertDocCount(rootResource.ID, "Size:>100000", 0)
|
||||
})
|
||||
|
||||
// FIXME: switch Title to audio.artist once
|
||||
// https://github.com/opencloud-eu/opencloud/pull/2632 lands
|
||||
// (KQL grammar then accepts dotted keys).
|
||||
It("preserves value case for fields not explicitly marked lowercase", func() {
|
||||
parentResource.Document.Title = "Some Title"
|
||||
err := eng.Upsert(parentResource.ID, parentResource)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
assertDocCount(rootResource.ID, `Title:"Some Title"`, 1)
|
||||
assertDocCount(rootResource.ID, `Title:"some title"`, 0)
|
||||
})
|
||||
})
|
||||
|
||||
Context("by filename", func() {
|
||||
|
||||
@@ -10,6 +10,17 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/pkg/kql"
|
||||
)
|
||||
|
||||
// lowercaseFields lists the bleve fields whose index mapping uses a lowercasing analyzer.
|
||||
// Values bound to these fields are pre-lowercased so that non-analyzed query types
|
||||
// (e.g. wildcard, fuzzy) still match the lowercased terms in the index.
|
||||
// Keep in sync with services/search/pkg/bleve/index.go NewMapping.
|
||||
var lowercaseFields = map[string]bool{
|
||||
"Name": true,
|
||||
"Tags": true,
|
||||
"Favorites": true,
|
||||
"Content": true,
|
||||
}
|
||||
|
||||
var _fields = map[string]string{
|
||||
"rootid": "RootID",
|
||||
"path": "Path",
|
||||
@@ -91,7 +102,7 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
|
||||
v = bleveEscaper.Replace(n.Value)
|
||||
}
|
||||
|
||||
if k != "Hidden" {
|
||||
if lowercaseFields[k] {
|
||||
v = strings.ToLower(v)
|
||||
}
|
||||
|
||||
|
||||
@@ -227,8 +227,8 @@ func Test_compile(t *testing.T) {
|
||||
},
|
||||
},
|
||||
want: query.NewConjunctionQuery([]query.Query{
|
||||
query.NewQueryStringQuery(`author:john\ smith`),
|
||||
query.NewQueryStringQuery(`author:jane`),
|
||||
query.NewQueryStringQuery(`author:John\ Smith`),
|
||||
query.NewQueryStringQuery(`author:Jane`),
|
||||
}),
|
||||
wantErr: false,
|
||||
},
|
||||
@@ -249,8 +249,8 @@ func Test_compile(t *testing.T) {
|
||||
},
|
||||
},
|
||||
want: query.NewConjunctionQuery([]query.Query{
|
||||
query.NewQueryStringQuery(`author:john\ smith`),
|
||||
query.NewQueryStringQuery(`author:jane`),
|
||||
query.NewQueryStringQuery(`author:John\ Smith`),
|
||||
query.NewQueryStringQuery(`author:Jane`),
|
||||
query.NewQueryStringQuery(`Tags:bestseller`),
|
||||
}),
|
||||
wantErr: false,
|
||||
|
||||
Reference in New Issue
Block a user