From ce5ec1b3dc3b84c50942a76d065d6c5f30093dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Duffeck?= Date: Thu, 5 Mar 2026 08:41:52 +0100 Subject: [PATCH] Add support for favorites to the search service --- .../opencloud/messages/search/v0/search.pb.go | 36 +++-- .../messages/settings/v0/settings.pb.go | 130 +++++++++--------- .../services/search/v0/search.swagger.json | 6 + .../opencloud/messages/search/v0/search.proto | 1 + services/search/pkg/bleve/backend.go | 1 + services/search/pkg/bleve/bleve.go | 23 ++-- services/search/pkg/bleve/index.go | 1 + services/search/pkg/content/basic.go | 5 + services/search/pkg/content/content.go | 23 ++-- services/search/pkg/query/bleve/compiler.go | 1 + services/search/pkg/search/search.go | 14 ++ services/search/pkg/search/service.go | 11 +- 12 files changed, 151 insertions(+), 101 deletions(-) diff --git a/protogen/gen/opencloud/messages/search/v0/search.pb.go b/protogen/gen/opencloud/messages/search/v0/search.pb.go index 8bbb1cadb..e5c74946e 100644 --- a/protogen/gen/opencloud/messages/search/v0/search.pb.go +++ b/protogen/gen/opencloud/messages/search/v0/search.pb.go @@ -559,6 +559,7 @@ type Entity struct { RemoteItemId *ResourceID `protobuf:"bytes,17,opt,name=remote_item_id,json=remoteItemId,proto3" json:"remote_item_id,omitempty"` Image *Image `protobuf:"bytes,18,opt,name=image,proto3" json:"image,omitempty"` Photo *Photo `protobuf:"bytes,19,opt,name=photo,proto3" json:"photo,omitempty"` + Favorites []string `protobuf:"bytes,20,rep,name=favorites,proto3" json:"favorites,omitempty"` } func (x *Entity) Reset() { @@ -726,6 +727,13 @@ func (x *Entity) GetPhoto() *Photo { return nil } +func (x *Entity) GetFavorites() []string { + if x != nil { + return x.Favorites + } + return nil +} + type Match struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -900,7 +908,7 @@ var file_opencloud_messages_search_v0_search_proto_rawDesc = []byte{ 0x6c, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x69, 0x73, 0x6f, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, - 0x65, 0x22, 0xdc, 0x06, 0x0a, 0x06, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x03, + 0x65, 0x22, 0xfa, 0x06, 0x0a, 0x06, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, @@ -954,18 +962,20 @@ var file_opencloud_messages_search_v0_search_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x74, 0x6f, - 0x22, 0x5b, 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3c, 0x0a, 0x06, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, - 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, - 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x42, 0x4d, 0x5a, - 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, - 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, - 0x75, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76, 0x30, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x73, 0x18, 0x14, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x73, 0x22, 0x5b, + 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3c, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x06, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x42, 0x4d, 0x5a, 0x4b, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f, 0x70, + 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76, 0x30, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/protogen/gen/opencloud/messages/settings/v0/settings.pb.go b/protogen/gen/opencloud/messages/settings/v0/settings.pb.go index 99641dcb8..aa9f81b32 100644 --- a/protogen/gen/opencloud/messages/settings/v0/settings.pb.go +++ b/protogen/gen/opencloud/messages/settings/v0/settings.pb.go @@ -627,13 +627,13 @@ type Bundle struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id" - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name" - Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=opencloud.messages.settings.v0.Bundle_Type" json:"type,omitempty"` // @gotags: yaml:"type" - Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty"` // @gotags: yaml:"extension" - DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name" - Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty"` // @gotags: yaml:"settings" - Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource" + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id" + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name" + Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=opencloud.messages.settings.v0.Bundle_Type" json:"type,omitempty" yaml:"type"` // @gotags: yaml:"type" + Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty" yaml:"extension"` // @gotags: yaml:"extension" + DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name" + Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty" yaml:"settings"` // @gotags: yaml:"settings" + Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource" } func (x *Bundle) Reset() { @@ -722,10 +722,10 @@ type Setting struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id" - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name" - DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name" - Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` // @gotags: yaml:"description" + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id" + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name" + DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name" + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` // @gotags: yaml:"description" // Types that are assignable to Value: // // *Setting_IntValue @@ -736,7 +736,7 @@ type Setting struct { // *Setting_PermissionValue // *Setting_MultiChoiceCollectionValue Value isSetting_Value `protobuf_oneof:"value"` - Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource" + Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource" } func (x *Setting) Reset() { @@ -867,31 +867,31 @@ type isSetting_Value interface { } type Setting_IntValue struct { - IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type Setting_StringValue struct { - StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type Setting_BoolValue struct { - BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } type Setting_SingleChoiceValue struct { - SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof"` // @gotags: yaml:"single_choice_value" + SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof" yaml:"single_choice_value"` // @gotags: yaml:"single_choice_value" } type Setting_MultiChoiceValue struct { - MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof"` // @gotags: yaml:"multi_choice_value" + MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof" yaml:"multi_choice_value"` // @gotags: yaml:"multi_choice_value" } type Setting_PermissionValue struct { - PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof"` // @gotags: yaml:"permission_value" + PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof" yaml:"permission_value"` // @gotags: yaml:"permission_value" } type Setting_MultiChoiceCollectionValue struct { - MultiChoiceCollectionValue *MultiChoiceCollection `protobuf:"bytes,12,opt,name=multi_choice_collection_value,json=multiChoiceCollectionValue,proto3,oneof"` // @gotags: yaml:"multi_choice_collection_value" + MultiChoiceCollectionValue *MultiChoiceCollection `protobuf:"bytes,12,opt,name=multi_choice_collection_value,json=multiChoiceCollectionValue,proto3,oneof" yaml:"multi_choice_collection_value"` // @gotags: yaml:"multi_choice_collection_value" } func (*Setting_IntValue) isSetting_Value() {} @@ -913,11 +913,11 @@ type Int struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" - Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty"` // @gotags: yaml:"min" - Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"` // @gotags: yaml:"max" - Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty"` // @gotags: yaml:"step" - Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder" + Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" + Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty" yaml:"min"` // @gotags: yaml:"min" + Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty" yaml:"max"` // @gotags: yaml:"max" + Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty" yaml:"step"` // @gotags: yaml:"step" + Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder" } func (x *Int) Reset() { @@ -992,11 +992,11 @@ type String struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" - Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty"` // @gotags: yaml:"required" - MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` // @gotags: yaml:"min_length" - MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` // @gotags: yaml:"max_length" - Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder" + Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" + Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty" yaml:"required"` // @gotags: yaml:"required" + MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty" yaml:"min_length"` // @gotags: yaml:"min_length" + MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty" yaml:"max_length"` // @gotags: yaml:"max_length" + Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder" } func (x *String) Reset() { @@ -1071,8 +1071,8 @@ type Bool struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" - Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` // @gotags: yaml:"label" + Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty" yaml:"label"` // @gotags: yaml:"label" } func (x *Bool) Reset() { @@ -1126,7 +1126,7 @@ type SingleChoiceList struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options" + Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options" } func (x *SingleChoiceList) Reset() { @@ -1173,7 +1173,7 @@ type MultiChoiceList struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options" + Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options" } func (x *MultiChoiceList) Reset() { @@ -1220,9 +1220,9 @@ type ListOption struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // @gotags: yaml:"value" - Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" - DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value" + Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` // @gotags: yaml:"value" + Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" + DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value" } func (x *ListOption) Reset() { @@ -1283,7 +1283,7 @@ type MultiChoiceCollection struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Options []*MultiChoiceCollectionOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options" + Options []*MultiChoiceCollectionOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options" } func (x *MultiChoiceCollection) Reset() { @@ -1330,10 +1330,10 @@ type MultiChoiceCollectionOption struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value *MultiChoiceCollectionOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // @gotags: yaml:"value" - Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` // @gotags: yaml:"key" - Attribute string `protobuf:"bytes,3,opt,name=attribute,proto3" json:"attribute,omitempty"` // @gotags: yaml:"attribute" - DisplayValue string `protobuf:"bytes,4,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value" + Value *MultiChoiceCollectionOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` // @gotags: yaml:"value" + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` // @gotags: yaml:"key" + Attribute string `protobuf:"bytes,3,opt,name=attribute,proto3" json:"attribute,omitempty" yaml:"attribute"` // @gotags: yaml:"attribute" + DisplayValue string `protobuf:"bytes,4,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value" } func (x *MultiChoiceCollectionOption) Reset() { @@ -1474,15 +1474,15 @@ type isMultiChoiceCollectionOptionValue_Option interface { } type MultiChoiceCollectionOptionValue_IntValue struct { - IntValue *Int `protobuf:"bytes,1,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue *Int `protobuf:"bytes,1,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type MultiChoiceCollectionOptionValue_StringValue struct { - StringValue *String `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue *String `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type MultiChoiceCollectionOptionValue_BoolValue struct { - BoolValue *Bool `protobuf:"bytes,3,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue *Bool `protobuf:"bytes,3,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } func (*MultiChoiceCollectionOptionValue_IntValue) isMultiChoiceCollectionOptionValue_Option() {} @@ -1496,8 +1496,8 @@ type Permission struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=opencloud.messages.settings.v0.Permission_Operation" json:"operation,omitempty"` // @gotags: yaml:"operation" - Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=opencloud.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty"` // @gotags: yaml:"constraint" + Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=opencloud.messages.settings.v0.Permission_Operation" json:"operation,omitempty" yaml:"operation"` // @gotags: yaml:"operation" + Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=opencloud.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty" yaml:"constraint"` // @gotags: yaml:"constraint" } func (x *Permission) Reset() { @@ -1552,12 +1552,12 @@ type Value struct { unknownFields protoimpl.UnknownFields // id is the id of the Value. It is generated on saving it. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id" - BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty"` // @gotags: yaml:"bundle_id" + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id" + BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty" yaml:"bundle_id"` // @gotags: yaml:"bundle_id" // setting_id is the id of the setting from within its bundle. - SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty"` // @gotags: yaml:"setting_id" - AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty"` // @gotags: yaml:"account_uuid" - Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource" + SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty" yaml:"setting_id"` // @gotags: yaml:"setting_id" + AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty" yaml:"account_uuid"` // @gotags: yaml:"account_uuid" + Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource" // Types that are assignable to Value: // // *Value_BoolValue @@ -1682,23 +1682,23 @@ type isValue_Value interface { } type Value_BoolValue struct { - BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } type Value_IntValue struct { - IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type Value_StringValue struct { - StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type Value_ListValue struct { - ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof"` // @gotags: yaml:"list_value" + ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof" yaml:"list_value"` // @gotags: yaml:"list_value" } type Value_CollectionValue struct { - CollectionValue *CollectionValue `protobuf:"bytes,10,opt,name=collection_value,json=collectionValue,proto3,oneof"` // @gotags: yaml:"collection_value" + CollectionValue *CollectionValue `protobuf:"bytes,10,opt,name=collection_value,json=collectionValue,proto3,oneof" yaml:"collection_value"` // @gotags: yaml:"collection_value" } func (*Value_BoolValue) isValue_Value() {} @@ -1716,7 +1716,7 @@ type ListValue struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values" + Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values" } func (x *ListValue) Reset() { @@ -1836,15 +1836,15 @@ type isListOptionValue_Option interface { } type ListOptionValue_StringValue struct { - StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type ListOptionValue_IntValue struct { - IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type ListOptionValue_BoolValue struct { - BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } func (*ListOptionValue_StringValue) isListOptionValue_Option() {} @@ -1858,7 +1858,7 @@ type CollectionValue struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Values []*CollectionOption `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values" + Values []*CollectionOption `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values" } func (x *CollectionValue) Reset() { @@ -1906,7 +1906,7 @@ type CollectionOption struct { unknownFields protoimpl.UnknownFields // required - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // @gotags: yaml:"key" + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` // @gotags: yaml:"key" // Types that are assignable to Option: // // *CollectionOption_IntValue @@ -1987,15 +1987,15 @@ type isCollectionOption_Option interface { } type CollectionOption_IntValue struct { - IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type CollectionOption_StringValue struct { - StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type CollectionOption_BoolValue struct { - BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } func (*CollectionOption_IntValue) isCollectionOption_Option() {} diff --git a/protogen/gen/opencloud/services/search/v0/search.swagger.json b/protogen/gen/opencloud/services/search/v0/search.swagger.json index df7b3661d..f04f10fc6 100644 --- a/protogen/gen/opencloud/services/search/v0/search.swagger.json +++ b/protogen/gen/opencloud/services/search/v0/search.swagger.json @@ -282,6 +282,12 @@ }, "photo": { "$ref": "#/definitions/v0Photo" + }, + "favorites": { + "type": "array", + "items": { + "type": "string" + } } } }, diff --git a/protogen/proto/opencloud/messages/search/v0/search.proto b/protogen/proto/opencloud/messages/search/v0/search.proto index b52b549b5..4633a2cee 100644 --- a/protogen/proto/opencloud/messages/search/v0/search.proto +++ b/protogen/proto/opencloud/messages/search/v0/search.proto @@ -79,6 +79,7 @@ message Entity { ResourceID remote_item_id = 17; Image image = 18; Photo photo = 19; + repeated string favorites = 20; } message Match { diff --git a/services/search/pkg/bleve/backend.go b/services/search/pkg/bleve/backend.go index 40c1ba367..8adcdda09 100644 --- a/services/search/pkg/bleve/backend.go +++ b/services/search/pkg/bleve/backend.go @@ -134,6 +134,7 @@ func (b *Backend) Search(_ context.Context, sir *searchService.SearchIndexReques MimeType: getFieldValue[string](hit.Fields, "MimeType"), Deleted: getFieldValue[bool](hit.Fields, "Deleted"), Tags: getFieldSliceValue[string](hit.Fields, "Tags"), + Favorites: getFieldSliceValue[string](hit.Fields, "Favorites"), Highlights: getFragmentValue(hit.Fragments, "Content", 0), Audio: getAudioValue[searchMessage.Audio](hit.Fields), Image: getImageValue[searchMessage.Image](hit.Fields), diff --git a/services/search/pkg/bleve/bleve.go b/services/search/pkg/bleve/bleve.go index bf68fabaf..64e5f1832 100644 --- a/services/search/pkg/bleve/bleve.go +++ b/services/search/pkg/bleve/bleve.go @@ -186,17 +186,18 @@ func matchToResource(match *bleveSearch.DocumentMatch) *search.Resource { Type: uint64(getFieldValue[float64](match.Fields, "Type")), Deleted: getFieldValue[bool](match.Fields, "Deleted"), Document: content.Document{ - Name: getFieldValue[string](match.Fields, "Name"), - Title: getFieldValue[string](match.Fields, "Title"), - Size: uint64(getFieldValue[float64](match.Fields, "Size")), - Mtime: getFieldValue[string](match.Fields, "Mtime"), - MimeType: getFieldValue[string](match.Fields, "MimeType"), - Content: getFieldValue[string](match.Fields, "Content"), - Tags: getFieldSliceValue[string](match.Fields, "Tags"), - Audio: getAudioValue[libregraph.Audio](match.Fields), - Image: getImageValue[libregraph.Image](match.Fields), - Location: getLocationValue[libregraph.GeoCoordinates](match.Fields), - Photo: getPhotoValue[libregraph.Photo](match.Fields), + Name: getFieldValue[string](match.Fields, "Name"), + Title: getFieldValue[string](match.Fields, "Title"), + Size: uint64(getFieldValue[float64](match.Fields, "Size")), + Mtime: getFieldValue[string](match.Fields, "Mtime"), + MimeType: getFieldValue[string](match.Fields, "MimeType"), + Content: getFieldValue[string](match.Fields, "Content"), + Tags: getFieldSliceValue[string](match.Fields, "Tags"), + Favorites: getFieldSliceValue[string](match.Fields, "Favorites"), + Audio: getAudioValue[libregraph.Audio](match.Fields), + Image: getImageValue[libregraph.Image](match.Fields), + Location: getLocationValue[libregraph.GeoCoordinates](match.Fields), + Photo: getPhotoValue[libregraph.Photo](match.Fields), }, } } diff --git a/services/search/pkg/bleve/index.go b/services/search/pkg/bleve/index.go index b910d4939..717ff6d58 100644 --- a/services/search/pkg/bleve/index.go +++ b/services/search/pkg/bleve/index.go @@ -52,6 +52,7 @@ func NewMapping() (mapping.IndexMapping, error) { docMapping := bleve.NewDocumentMapping() docMapping.AddFieldMappingsAt("Name", nameMapping) docMapping.AddFieldMappingsAt("Tags", lowercaseMapping) + docMapping.AddFieldMappingsAt("Favorites", lowercaseMapping) docMapping.AddFieldMappingsAt("Content", fulltextFieldMapping) indexMapping := bleve.NewIndexMapping() diff --git a/services/search/pkg/content/basic.go b/services/search/pkg/content/basic.go index 77ca9163f..981acfd22 100644 --- a/services/search/pkg/content/basic.go +++ b/services/search/pkg/content/basic.go @@ -2,10 +2,12 @@ package content import ( "context" + "strings" "time" storageProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/opencloud-eu/opencloud/pkg/log" + "github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node" "github.com/opencloud-eu/reva/v2/pkg/tags" "github.com/opencloud-eu/reva/v2/pkg/utils" ) @@ -32,6 +34,9 @@ func (b Basic) Extract(_ context.Context, ri *storageProvider.ResourceInfo) (Doc if t, ok := m["tags"]; ok { doc.Tags = tags.New(t).AsSlice() } + if t, ok := m[node.AllFavoritesKey]; ok && len(t) > 0 { + doc.Favorites = strings.Split(t, ",") + } } if ri.Mtime != nil { diff --git a/services/search/pkg/content/content.go b/services/search/pkg/content/content.go index e43f1cd03..e18535167 100644 --- a/services/search/pkg/content/content.go +++ b/services/search/pkg/content/content.go @@ -14,17 +14,18 @@ func init() { // Document wraps all resource meta fields, // it is used as a content extraction result. type Document struct { - Title string - Name string - Content string - Size uint64 - Mtime string - MimeType string - Tags []string - Audio *libregraph.Audio `json:"audio,omitempty"` - Image *libregraph.Image `json:"image,omitempty"` - Location *libregraph.GeoCoordinates `json:"location,omitempty"` - Photo *libregraph.Photo `json:"photo,omitempty"` + Title string + Name string + Content string + Size uint64 + Mtime string + MimeType string + Tags []string + Favorites []string + Audio *libregraph.Audio `json:"audio,omitempty"` + Image *libregraph.Image `json:"image,omitempty"` + Location *libregraph.GeoCoordinates `json:"location,omitempty"` + Photo *libregraph.Photo `json:"photo,omitempty"` } func CleanString(content, langCode string) string { diff --git a/services/search/pkg/query/bleve/compiler.go b/services/search/pkg/query/bleve/compiler.go index 77d151651..e9d466e93 100644 --- a/services/search/pkg/query/bleve/compiler.go +++ b/services/search/pkg/query/bleve/compiler.go @@ -23,6 +23,7 @@ var _fields = map[string]string{ "tags": "Tags", "content": "Content", "hidden": "Hidden", + "favorite": "Favorites", } // The following quoted string enumerates the characters which may be escaped: "+-=&|>