mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-10-07 03:11:57 -04:00
feat(search): add metric aggregations
sum/min/max/avg over a numeric field: bleve folds the accumulators from doc values, OpenSearch reads them from a stats aggregation, the service layer reduces them to the value of the kind after the cross-space merge. The proto gains MetricDefinition, MetricKind and Metric, which travels as accumulators (sum, count, min, max) so the merge works whatever the kind; value is set after the merge and absent for a metric without a single value. A metric is only valid on a numeric field, and only one of bucketDefinition and metricDefinition at a time. AGG-06, 18 and 21 in the parity suite.
This commit is contained in:
1 parent
b2d8a13c24
commit
0dbd8d6963
18 files changed
+954
-228
No files matched your search
@@ -25,6 +25,61 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type MetricKind int32
|
||||
|
||||
const (
|
||||
MetricKind_METRIC_KIND_UNSPECIFIED MetricKind = 0
|
||||
MetricKind_METRIC_KIND_SUM MetricKind = 1
|
||||
MetricKind_METRIC_KIND_MIN MetricKind = 2
|
||||
MetricKind_METRIC_KIND_MAX MetricKind = 3
|
||||
MetricKind_METRIC_KIND_AVG MetricKind = 4
|
||||
)
|
||||
|
||||
// Enum value maps for MetricKind.
|
||||
var (
|
||||
MetricKind_name = map[int32]string{
|
||||
0: "METRIC_KIND_UNSPECIFIED",
|
||||
1: "METRIC_KIND_SUM",
|
||||
2: "METRIC_KIND_MIN",
|
||||
3: "METRIC_KIND_MAX",
|
||||
4: "METRIC_KIND_AVG",
|
||||
}
|
||||
MetricKind_value = map[string]int32{
|
||||
"METRIC_KIND_UNSPECIFIED": 0,
|
||||
"METRIC_KIND_SUM": 1,
|
||||
"METRIC_KIND_MIN": 2,
|
||||
"METRIC_KIND_MAX": 3,
|
||||
"METRIC_KIND_AVG": 4,
|
||||
}
|
||||
)
|
||||
|
||||
func (x MetricKind) Enum() *MetricKind {
|
||||
p := new(MetricKind)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x MetricKind) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (MetricKind) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_opencloud_services_search_v0_search_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (MetricKind) Type() protoreflect.EnumType {
|
||||
return &file_opencloud_services_search_v0_search_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x MetricKind) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use MetricKind.Descriptor instead.
|
||||
func (MetricKind) EnumDescriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type BucketSortBy int32
|
||||
|
||||
const (
|
||||
@@ -61,11 +116,11 @@ func (x BucketSortBy) String() string {
|
||||
}
|
||||
|
||||
func (BucketSortBy) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_opencloud_services_search_v0_search_proto_enumTypes[0].Descriptor()
|
||||
return file_opencloud_services_search_v0_search_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (BucketSortBy) Type() protoreflect.EnumType {
|
||||
return &file_opencloud_services_search_v0_search_proto_enumTypes[0]
|
||||
return &file_opencloud_services_search_v0_search_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x BucketSortBy) Number() protoreflect.EnumNumber {
|
||||
@@ -74,7 +129,7 @@ func (x BucketSortBy) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use BucketSortBy.Descriptor instead.
|
||||
func (BucketSortBy) EnumDescriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{0}
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type IndexSpaceResponse_Status int32
|
||||
@@ -117,11 +172,11 @@ func (x IndexSpaceResponse_Status) String() string {
|
||||
}
|
||||
|
||||
func (IndexSpaceResponse_Status) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_opencloud_services_search_v0_search_proto_enumTypes[1].Descriptor()
|
||||
return file_opencloud_services_search_v0_search_proto_enumTypes[2].Descriptor()
|
||||
}
|
||||
|
||||
func (IndexSpaceResponse_Status) Type() protoreflect.EnumType {
|
||||
return &file_opencloud_services_search_v0_search_proto_enumTypes[1]
|
||||
return &file_opencloud_services_search_v0_search_proto_enumTypes[2]
|
||||
}
|
||||
|
||||
func (x IndexSpaceResponse_Status) Number() protoreflect.EnumNumber {
|
||||
@@ -130,7 +185,7 @@ func (x IndexSpaceResponse_Status) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use IndexSpaceResponse_Status.Descriptor instead.
|
||||
func (IndexSpaceResponse_Status) EnumDescriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{10, 0}
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{12, 0}
|
||||
}
|
||||
|
||||
type SearchRequest struct {
|
||||
@@ -465,14 +520,20 @@ type AggregationOption struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Required. The indexed field to aggregate on.
|
||||
// Required. The indexed field to aggregate on (for terms/range
|
||||
// aggregations) or to reduce (for metric aggregations).
|
||||
Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"`
|
||||
// Optional. Maximum number of buckets to return for a terms aggregation,
|
||||
// applied after the cross-space merge. 0 returns every bucket. Ignored for
|
||||
// range aggregations.
|
||||
// range and metric aggregations.
|
||||
Size int32 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"`
|
||||
// Optional. Controls bucket selection, ordering and filtering.
|
||||
// Ignored for metric aggregations.
|
||||
BucketDefinition *BucketDefinition `protobuf:"bytes,3,opt,name=bucket_definition,json=bucketDefinition,proto3" json:"bucket_definition,omitempty"`
|
||||
// Optional. When set, this aggregation is a scalar metric over `field`
|
||||
// rather than a bucket aggregation; the corresponding AggregationResult
|
||||
// carries `metric` instead of `buckets`.
|
||||
MetricDefinition *MetricDefinition `protobuf:"bytes,4,opt,name=metric_definition,json=metricDefinition,proto3" json:"metric_definition,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AggregationOption) Reset() {
|
||||
@@ -528,6 +589,60 @@ func (x *AggregationOption) GetBucketDefinition() *BucketDefinition {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *AggregationOption) GetMetricDefinition() *MetricDefinition {
|
||||
if x != nil {
|
||||
return x.MetricDefinition
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MetricDefinition struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Kind MetricKind `protobuf:"varint,1,opt,name=kind,proto3,enum=opencloud.services.search.v0.MetricKind" json:"kind,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MetricDefinition) Reset() {
|
||||
*x = MetricDefinition{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MetricDefinition) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MetricDefinition) ProtoMessage() {}
|
||||
|
||||
func (x *MetricDefinition) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use MetricDefinition.ProtoReflect.Descriptor instead.
|
||||
func (*MetricDefinition) Descriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *MetricDefinition) GetKind() MetricKind {
|
||||
if x != nil {
|
||||
return x.Kind
|
||||
}
|
||||
return MetricKind_METRIC_KIND_UNSPECIFIED
|
||||
}
|
||||
|
||||
type BucketDefinition struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -546,7 +661,7 @@ type BucketDefinition struct {
|
||||
func (x *BucketDefinition) Reset() {
|
||||
*x = BucketDefinition{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[5]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -559,7 +674,7 @@ func (x *BucketDefinition) String() string {
|
||||
func (*BucketDefinition) ProtoMessage() {}
|
||||
|
||||
func (x *BucketDefinition) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[5]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -572,7 +687,7 @@ func (x *BucketDefinition) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use BucketDefinition.ProtoReflect.Descriptor instead.
|
||||
func (*BucketDefinition) Descriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{5}
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *BucketDefinition) GetSortBy() BucketSortBy {
|
||||
@@ -618,7 +733,7 @@ type BucketRange struct {
|
||||
func (x *BucketRange) Reset() {
|
||||
*x = BucketRange{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[6]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -631,7 +746,7 @@ func (x *BucketRange) String() string {
|
||||
func (*BucketRange) ProtoMessage() {}
|
||||
|
||||
func (x *BucketRange) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[6]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -644,7 +759,7 @@ func (x *BucketRange) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use BucketRange.ProtoReflect.Descriptor instead.
|
||||
func (*BucketRange) Descriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{6}
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *BucketRange) GetFrom() string {
|
||||
@@ -669,12 +784,15 @@ type AggregationResult struct {
|
||||
|
||||
Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"`
|
||||
Buckets []*Bucket `protobuf:"bytes,2,rep,name=buckets,proto3" json:"buckets,omitempty"`
|
||||
// Result of a metric aggregation (metric_definition set on the
|
||||
// corresponding AggregationOption). Unset for terms/range aggregations.
|
||||
Metric *Metric `protobuf:"bytes,3,opt,name=metric,proto3" json:"metric,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AggregationResult) Reset() {
|
||||
*x = AggregationResult{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[7]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -687,7 +805,7 @@ func (x *AggregationResult) String() string {
|
||||
func (*AggregationResult) ProtoMessage() {}
|
||||
|
||||
func (x *AggregationResult) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[7]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -700,7 +818,7 @@ func (x *AggregationResult) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use AggregationResult.ProtoReflect.Descriptor instead.
|
||||
func (*AggregationResult) Descriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{7}
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *AggregationResult) GetField() string {
|
||||
@@ -717,6 +835,106 @@ func (x *AggregationResult) GetBuckets() []*Bucket {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *AggregationResult) GetMetric() *Metric {
|
||||
if x != nil {
|
||||
return x.Metric
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Metric struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Echoes the kind of the corresponding MetricDefinition.
|
||||
Kind MetricKind `protobuf:"varint,1,opt,name=kind,proto3,enum=opencloud.services.search.v0.MetricKind" json:"kind,omitempty"`
|
||||
// The reduced value. Set by the service layer after the cross-space
|
||||
// merge, unset when no match carries a value.
|
||||
Value *float64 `protobuf:"fixed64,2,opt,name=value,proto3,oneof" json:"value,omitempty"`
|
||||
// Accumulators over the values of all matches. An engine fills all of
|
||||
// them, whatever the kind, so the service layer can merge results across
|
||||
// spaces without knowing the kind (an average of averages is no average).
|
||||
Sum float64 `protobuf:"fixed64,3,opt,name=sum,proto3" json:"sum,omitempty"`
|
||||
Count int64 `protobuf:"varint,4,opt,name=count,proto3" json:"count,omitempty"`
|
||||
Min float64 `protobuf:"fixed64,5,opt,name=min,proto3" json:"min,omitempty"`
|
||||
Max float64 `protobuf:"fixed64,6,opt,name=max,proto3" json:"max,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Metric) Reset() {
|
||||
*x = Metric{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Metric) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Metric) ProtoMessage() {}
|
||||
|
||||
func (x *Metric) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Metric.ProtoReflect.Descriptor instead.
|
||||
func (*Metric) Descriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *Metric) GetKind() MetricKind {
|
||||
if x != nil {
|
||||
return x.Kind
|
||||
}
|
||||
return MetricKind_METRIC_KIND_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *Metric) GetValue() float64 {
|
||||
if x != nil && x.Value != nil {
|
||||
return *x.Value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Metric) GetSum() float64 {
|
||||
if x != nil {
|
||||
return x.Sum
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Metric) GetCount() int64 {
|
||||
if x != nil {
|
||||
return x.Count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Metric) GetMin() float64 {
|
||||
if x != nil {
|
||||
return x.Min
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Metric) GetMax() float64 {
|
||||
if x != nil {
|
||||
return x.Max
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Bucket struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -729,7 +947,7 @@ type Bucket struct {
|
||||
func (x *Bucket) Reset() {
|
||||
*x = Bucket{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[8]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -742,7 +960,7 @@ func (x *Bucket) String() string {
|
||||
func (*Bucket) ProtoMessage() {}
|
||||
|
||||
func (x *Bucket) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[8]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -755,7 +973,7 @@ func (x *Bucket) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Bucket.ProtoReflect.Descriptor instead.
|
||||
func (*Bucket) Descriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{8}
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *Bucket) GetKey() string {
|
||||
@@ -786,7 +1004,7 @@ type IndexSpaceRequest struct {
|
||||
func (x *IndexSpaceRequest) Reset() {
|
||||
*x = IndexSpaceRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[9]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -799,7 +1017,7 @@ func (x *IndexSpaceRequest) String() string {
|
||||
func (*IndexSpaceRequest) ProtoMessage() {}
|
||||
|
||||
func (x *IndexSpaceRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[9]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[11]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -812,7 +1030,7 @@ func (x *IndexSpaceRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use IndexSpaceRequest.ProtoReflect.Descriptor instead.
|
||||
func (*IndexSpaceRequest) Descriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{9}
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
func (x *IndexSpaceRequest) GetSpaceId() string {
|
||||
@@ -865,7 +1083,7 @@ type IndexSpaceResponse struct {
|
||||
func (x *IndexSpaceResponse) Reset() {
|
||||
*x = IndexSpaceResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[10]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -878,7 +1096,7 @@ func (x *IndexSpaceResponse) String() string {
|
||||
func (*IndexSpaceResponse) ProtoMessage() {}
|
||||
|
||||
func (x *IndexSpaceResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[10]
|
||||
mi := &file_opencloud_services_search_v0_search_proto_msgTypes[12]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -891,7 +1109,7 @@ func (x *IndexSpaceResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use IndexSpaceResponse.ProtoReflect.Descriptor instead.
|
||||
func (*IndexSpaceResponse) Descriptor() ([]byte, []int) {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{10}
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{12}
|
||||
}
|
||||
|
||||
func (x *IndexSpaceResponse) GetSpaceId() string {
|
||||
@@ -1026,7 +1244,7 @@ var file_opencloud_services_search_v0_search_proto_rawDesc = []byte{
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e,
|
||||
0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c,
|
||||
0x74, 0x52, 0x0c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22,
|
||||
0xa6, 0x01, 0x0a, 0x11, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f,
|
||||
0x89, 0x02, 0x0a, 0x11, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x18, 0x0a, 0x04, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x01, 0x52,
|
||||
@@ -1036,130 +1254,165 @@ var file_opencloud_services_search_v0_search_proto_rawDesc = []byte{
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e,
|
||||
0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x42, 0x04, 0xe2, 0x41, 0x01, 0x01, 0x52, 0x10, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x44, 0x65,
|
||||
0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe4, 0x01, 0x0a, 0x10, 0x42, 0x75, 0x63,
|
||||
0x6b, 0x65, 0x74, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a,
|
||||
0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a,
|
||||
0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x42, 0x75,
|
||||
0x63, 0x6b, 0x65, 0x74, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x52, 0x06, 0x73, 0x6f, 0x72, 0x74,
|
||||
0x42, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x64,
|
||||
0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x44, 0x65, 0x73,
|
||||
0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x69, 0x6d,
|
||||
0x75, 0x6d, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c,
|
||||
0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x06,
|
||||
0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6f,
|
||||
0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x42, 0x75, 0x63, 0x6b,
|
||||
0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22,
|
||||
0x31, 0x0a, 0x0b, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72,
|
||||
0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
|
||||
0x74, 0x6f, 0x22, 0x69, 0x0a, 0x11, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x3e, 0x0a,
|
||||
0x07, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24,
|
||||
0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x42, 0x75,
|
||||
0x63, 0x6b, 0x65, 0x74, 0x52, 0x07, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x22, 0x30, 0x0a,
|
||||
0x06, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22,
|
||||
0x94, 0x01, 0x0a, 0x11, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64,
|
||||
0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72,
|
||||
0x63, 0x65, 0x5f, 0x72, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26,
|
||||
0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x05, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x01, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75,
|
||||
0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0xfa, 0x02, 0x0a, 0x12, 0x49, 0x6e, 0x64, 0x65, 0x78,
|
||||
0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a,
|
||||
0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x73, 0x70, 0x61, 0x63,
|
||||
0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x70, 0x61,
|
||||
0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x65, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x53, 0x70, 0x61, 0x63, 0x65,
|
||||
0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x70,
|
||||
0x61, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x4f, 0x0a, 0x06, 0x73, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x6f, 0x70, 0x65,
|
||||
0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x61, 0x0a, 0x11, 0x6d, 0x65, 0x74, 0x72,
|
||||
0x69, 0x63, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e,
|
||||
0x76, 0x30, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x01, 0x52, 0x10, 0x6d, 0x65, 0x74, 0x72, 0x69,
|
||||
0x63, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x10, 0x4d,
|
||||
0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x3c, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e,
|
||||
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x4d, 0x65, 0x74,
|
||||
0x72, 0x69, 0x63, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xe4, 0x01,
|
||||
0x0a, 0x10, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e,
|
||||
0x76, 0x30, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x52,
|
||||
0x06, 0x73, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x64, 0x65,
|
||||
0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c,
|
||||
0x69, 0x73, 0x44, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x0d,
|
||||
0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x12, 0x41, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x29, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30,
|
||||
0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x72, 0x61,
|
||||
0x6e, 0x67, 0x65, 0x73, 0x22, 0x31, 0x0a, 0x0b, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x61,
|
||||
0x6e, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x11, 0x41, 0x67, 0x67, 0x72,
|
||||
0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69,
|
||||
0x65, 0x6c, 0x64, 0x12, 0x3e, 0x0a, 0x07, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x02,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68,
|
||||
0x2e, 0x76, 0x30, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x07, 0x62, 0x75, 0x63, 0x6b,
|
||||
0x65, 0x74, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e,
|
||||
0x76, 0x30, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x72, 0x69,
|
||||
0x63, 0x22, 0xb7, 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x3c, 0x0a, 0x04,
|
||||
0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x6f, 0x70, 0x65,
|
||||
0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53,
|
||||
0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x56, 0x0a, 0x06, 0x53,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
|
||||
0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41,
|
||||
0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x12, 0x0a,
|
||||
0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10,
|
||||
0x02, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f,
|
||||
0x52, 0x10, 0x03, 0x2a, 0x8c, 0x01, 0x0a, 0x0c, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x6f,
|
||||
0x72, 0x74, 0x42, 0x79, 0x12, 0x1e, 0x0a, 0x1a, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53,
|
||||
0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
|
||||
0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53,
|
||||
0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x20,
|
||||
0x0a, 0x1c, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59,
|
||||
0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x02,
|
||||
0x12, 0x20, 0x0a, 0x1c, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f,
|
||||
0x42, 0x59, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x53, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52,
|
||||
0x10, 0x03, 0x32, 0xb3, 0x02, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x85, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
|
||||
0x12, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e,
|
||||
0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e,
|
||||
0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
|
||||
0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x88, 0x01, 0x01, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x01, 0x52, 0x03, 0x73, 0x75, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x10, 0x0a,
|
||||
0x03, 0x6d, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6d, 0x61,
|
||||
0x78, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x30, 0x0a, 0x06, 0x42,
|
||||
0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x94, 0x01,
|
||||
0x0a, 0x11, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x17,
|
||||
0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72, 0x63, 0x65,
|
||||
0x5f, 0x72, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c,
|
||||
0x66, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0b,
|
||||
0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x05, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x01, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72,
|
||||
0x65, 0x6e, 0x63, 0x79, 0x22, 0xfa, 0x02, 0x0a, 0x12, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70,
|
||||
0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x73,
|
||||
0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73,
|
||||
0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
|
||||
0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
|
||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x65, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x53, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x70, 0x61, 0x63,
|
||||
0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x4f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63,
|
||||
0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65,
|
||||
0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61,
|
||||
0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x56, 0x0a, 0x06, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e,
|
||||
0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55,
|
||||
0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x53,
|
||||
0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, 0x12,
|
||||
0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10,
|
||||
0x03, 0x2a, 0x7d, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4b, 0x69, 0x6e, 0x64, 0x12,
|
||||
0x1b, 0x0a, 0x17, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55,
|
||||
0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f,
|
||||
0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x53, 0x55, 0x4d, 0x10,
|
||||
0x01, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, 0x44,
|
||||
0x5f, 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43,
|
||||
0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x58, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d,
|
||||
0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x56, 0x47, 0x10, 0x04,
|
||||
0x2a, 0x8c, 0x01, 0x0a, 0x0c, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x6f, 0x72, 0x74, 0x42,
|
||||
0x79, 0x12, 0x1e, 0x0a, 0x1a, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x4f, 0x52, 0x54,
|
||||
0x5f, 0x42, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
|
||||
0x00, 0x12, 0x18, 0x0a, 0x14, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x4f, 0x52, 0x54,
|
||||
0x5f, 0x42, 0x59, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x42,
|
||||
0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f, 0x4b, 0x45,
|
||||
0x59, 0x5f, 0x41, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x20, 0x0a,
|
||||
0x1c, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59, 0x5f,
|
||||
0x4b, 0x45, 0x59, 0x5f, 0x41, 0x53, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x03, 0x32,
|
||||
0xb3, 0x02, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x12, 0x85, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x2b, 0x2e,
|
||||
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61,
|
||||
0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f,
|
||||
0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x98, 0x01,
|
||||
0x0a, 0x0a, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x6f,
|
||||
0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e,
|
||||
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78,
|
||||
0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x30, 0x01, 0x32, 0xa7, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x95, 0x01, 0x0a, 0x06, 0x53,
|
||||
0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x30, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75,
|
||||
0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63,
|
||||
0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65, 0x78,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c,
|
||||
0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61,
|
||||
0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73,
|
||||
0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2f, 0x73, 0x65, 0x61, 0x72,
|
||||
0x63, 0x68, 0x42, 0xf2, 0x02, 0x5a, 0x4a, 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,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76,
|
||||
0x30, 0x92, 0x41, 0xa2, 0x02, 0x12, 0xb7, 0x01, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c,
|
||||
0x6f, 0x75, 0x64, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x51, 0x0a, 0x0e, 0x4f, 0x70,
|
||||
0x65, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x12, 0x29, 0x68, 0x74,
|
||||
0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 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, 0x1a, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x40, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x65, 0x75, 0x2a, 0x49, 0x0a,
|
||||
0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30, 0x12, 0x3b, 0x68, 0x74, 0x74,
|
||||
0x70, 0x73, 0x3a, 0x2f, 0x2f, 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, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e,
|
||||
0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2a,
|
||||
0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x3e, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c,
|
||||
0x6f, 0x70, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x2a, 0x68, 0x74, 0x74,
|
||||
0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x6f, 0x63, 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c,
|
||||
0x6f, 0x75, 0x64, 0x2e, 0x65, 0x75, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f,
|
||||
0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6f, 0x70, 0x65,
|
||||
0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a,
|
||||
0x3a, 0x01, 0x2a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61,
|
||||
0x72, 0x63, 0x68, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x98, 0x01, 0x0a, 0x0a, 0x49,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e,
|
||||
0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73,
|
||||
0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70,
|
||||
0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6f, 0x70, 0x65,
|
||||
0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53,
|
||||
0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30,
|
||||
0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x73, 0x70,
|
||||
0x61, 0x63, 0x65, 0x30, 0x01, 0x32, 0xa7, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x50,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x95, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72,
|
||||
0x63, 0x68, 0x12, 0x30, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76,
|
||||
0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68,
|
||||
0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a,
|
||||
0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72,
|
||||
0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x42,
|
||||
0xf2, 0x02, 0x5a, 0x4a, 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, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76, 0x30, 0x92, 0x41,
|
||||
0xa2, 0x02, 0x12, 0xb7, 0x01, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64,
|
||||
0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x51, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x6e, 0x43,
|
||||
0x6c, 0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x12, 0x29, 0x68, 0x74, 0x74, 0x70, 0x73,
|
||||
0x3a, 0x2f, 0x2f, 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, 0x1a, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x6f, 0x70,
|
||||
0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x65, 0x75, 0x2a, 0x49, 0x0a, 0x0a, 0x41, 0x70,
|
||||
0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30, 0x12, 0x3b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
|
||||
0x2f, 0x2f, 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, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49,
|
||||
0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02,
|
||||
0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73,
|
||||
0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f,
|
||||
0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x3e, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65,
|
||||
0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
|
||||
0x2f, 0x2f, 0x64, 0x6f, 0x63, 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
|
||||
0x2e, 0x65, 0x75, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x65, 0x61,
|
||||
0x72, 0x63, 0x68, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -1174,52 +1427,59 @@ func file_opencloud_services_search_v0_search_proto_rawDescGZIP() []byte {
|
||||
return file_opencloud_services_search_v0_search_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_opencloud_services_search_v0_search_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||
var file_opencloud_services_search_v0_search_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_opencloud_services_search_v0_search_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
|
||||
var file_opencloud_services_search_v0_search_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
|
||||
var file_opencloud_services_search_v0_search_proto_goTypes = []interface{}{
|
||||
(BucketSortBy)(0), // 0: opencloud.services.search.v0.BucketSortBy
|
||||
(IndexSpaceResponse_Status)(0), // 1: opencloud.services.search.v0.IndexSpaceResponse.Status
|
||||
(*SearchRequest)(nil), // 2: opencloud.services.search.v0.SearchRequest
|
||||
(*SearchResponse)(nil), // 3: opencloud.services.search.v0.SearchResponse
|
||||
(*SearchIndexRequest)(nil), // 4: opencloud.services.search.v0.SearchIndexRequest
|
||||
(*SearchIndexResponse)(nil), // 5: opencloud.services.search.v0.SearchIndexResponse
|
||||
(*AggregationOption)(nil), // 6: opencloud.services.search.v0.AggregationOption
|
||||
(*BucketDefinition)(nil), // 7: opencloud.services.search.v0.BucketDefinition
|
||||
(*BucketRange)(nil), // 8: opencloud.services.search.v0.BucketRange
|
||||
(*AggregationResult)(nil), // 9: opencloud.services.search.v0.AggregationResult
|
||||
(*Bucket)(nil), // 10: opencloud.services.search.v0.Bucket
|
||||
(*IndexSpaceRequest)(nil), // 11: opencloud.services.search.v0.IndexSpaceRequest
|
||||
(*IndexSpaceResponse)(nil), // 12: opencloud.services.search.v0.IndexSpaceResponse
|
||||
(*v0.Reference)(nil), // 13: opencloud.messages.search.v0.Reference
|
||||
(*v0.Match)(nil), // 14: opencloud.messages.search.v0.Match
|
||||
(*durationpb.Duration)(nil), // 15: google.protobuf.Duration
|
||||
(MetricKind)(0), // 0: opencloud.services.search.v0.MetricKind
|
||||
(BucketSortBy)(0), // 1: opencloud.services.search.v0.BucketSortBy
|
||||
(IndexSpaceResponse_Status)(0), // 2: opencloud.services.search.v0.IndexSpaceResponse.Status
|
||||
(*SearchRequest)(nil), // 3: opencloud.services.search.v0.SearchRequest
|
||||
(*SearchResponse)(nil), // 4: opencloud.services.search.v0.SearchResponse
|
||||
(*SearchIndexRequest)(nil), // 5: opencloud.services.search.v0.SearchIndexRequest
|
||||
(*SearchIndexResponse)(nil), // 6: opencloud.services.search.v0.SearchIndexResponse
|
||||
(*AggregationOption)(nil), // 7: opencloud.services.search.v0.AggregationOption
|
||||
(*MetricDefinition)(nil), // 8: opencloud.services.search.v0.MetricDefinition
|
||||
(*BucketDefinition)(nil), // 9: opencloud.services.search.v0.BucketDefinition
|
||||
(*BucketRange)(nil), // 10: opencloud.services.search.v0.BucketRange
|
||||
(*AggregationResult)(nil), // 11: opencloud.services.search.v0.AggregationResult
|
||||
(*Metric)(nil), // 12: opencloud.services.search.v0.Metric
|
||||
(*Bucket)(nil), // 13: opencloud.services.search.v0.Bucket
|
||||
(*IndexSpaceRequest)(nil), // 14: opencloud.services.search.v0.IndexSpaceRequest
|
||||
(*IndexSpaceResponse)(nil), // 15: opencloud.services.search.v0.IndexSpaceResponse
|
||||
(*v0.Reference)(nil), // 16: opencloud.messages.search.v0.Reference
|
||||
(*v0.Match)(nil), // 17: opencloud.messages.search.v0.Match
|
||||
(*durationpb.Duration)(nil), // 18: google.protobuf.Duration
|
||||
}
|
||||
var file_opencloud_services_search_v0_search_proto_depIdxs = []int32{
|
||||
13, // 0: opencloud.services.search.v0.SearchRequest.ref:type_name -> opencloud.messages.search.v0.Reference
|
||||
6, // 1: opencloud.services.search.v0.SearchRequest.aggregations:type_name -> opencloud.services.search.v0.AggregationOption
|
||||
14, // 2: opencloud.services.search.v0.SearchResponse.matches:type_name -> opencloud.messages.search.v0.Match
|
||||
9, // 3: opencloud.services.search.v0.SearchResponse.aggregations:type_name -> opencloud.services.search.v0.AggregationResult
|
||||
13, // 4: opencloud.services.search.v0.SearchIndexRequest.ref:type_name -> opencloud.messages.search.v0.Reference
|
||||
6, // 5: opencloud.services.search.v0.SearchIndexRequest.aggregations:type_name -> opencloud.services.search.v0.AggregationOption
|
||||
14, // 6: opencloud.services.search.v0.SearchIndexResponse.matches:type_name -> opencloud.messages.search.v0.Match
|
||||
9, // 7: opencloud.services.search.v0.SearchIndexResponse.aggregations:type_name -> opencloud.services.search.v0.AggregationResult
|
||||
7, // 8: opencloud.services.search.v0.AggregationOption.bucket_definition:type_name -> opencloud.services.search.v0.BucketDefinition
|
||||
0, // 9: opencloud.services.search.v0.BucketDefinition.sort_by:type_name -> opencloud.services.search.v0.BucketSortBy
|
||||
8, // 10: opencloud.services.search.v0.BucketDefinition.ranges:type_name -> opencloud.services.search.v0.BucketRange
|
||||
10, // 11: opencloud.services.search.v0.AggregationResult.buckets:type_name -> opencloud.services.search.v0.Bucket
|
||||
15, // 12: opencloud.services.search.v0.IndexSpaceResponse.space_duration:type_name -> google.protobuf.Duration
|
||||
1, // 13: opencloud.services.search.v0.IndexSpaceResponse.status:type_name -> opencloud.services.search.v0.IndexSpaceResponse.Status
|
||||
2, // 14: opencloud.services.search.v0.SearchProvider.Search:input_type -> opencloud.services.search.v0.SearchRequest
|
||||
11, // 15: opencloud.services.search.v0.SearchProvider.IndexSpace:input_type -> opencloud.services.search.v0.IndexSpaceRequest
|
||||
4, // 16: opencloud.services.search.v0.IndexProvider.Search:input_type -> opencloud.services.search.v0.SearchIndexRequest
|
||||
3, // 17: opencloud.services.search.v0.SearchProvider.Search:output_type -> opencloud.services.search.v0.SearchResponse
|
||||
12, // 18: opencloud.services.search.v0.SearchProvider.IndexSpace:output_type -> opencloud.services.search.v0.IndexSpaceResponse
|
||||
5, // 19: opencloud.services.search.v0.IndexProvider.Search:output_type -> opencloud.services.search.v0.SearchIndexResponse
|
||||
17, // [17:20] is the sub-list for method output_type
|
||||
14, // [14:17] is the sub-list for method input_type
|
||||
14, // [14:14] is the sub-list for extension type_name
|
||||
14, // [14:14] is the sub-list for extension extendee
|
||||
0, // [0:14] is the sub-list for field type_name
|
||||
16, // 0: opencloud.services.search.v0.SearchRequest.ref:type_name -> opencloud.messages.search.v0.Reference
|
||||
7, // 1: opencloud.services.search.v0.SearchRequest.aggregations:type_name -> opencloud.services.search.v0.AggregationOption
|
||||
17, // 2: opencloud.services.search.v0.SearchResponse.matches:type_name -> opencloud.messages.search.v0.Match
|
||||
11, // 3: opencloud.services.search.v0.SearchResponse.aggregations:type_name -> opencloud.services.search.v0.AggregationResult
|
||||
16, // 4: opencloud.services.search.v0.SearchIndexRequest.ref:type_name -> opencloud.messages.search.v0.Reference
|
||||
7, // 5: opencloud.services.search.v0.SearchIndexRequest.aggregations:type_name -> opencloud.services.search.v0.AggregationOption
|
||||
17, // 6: opencloud.services.search.v0.SearchIndexResponse.matches:type_name -> opencloud.messages.search.v0.Match
|
||||
11, // 7: opencloud.services.search.v0.SearchIndexResponse.aggregations:type_name -> opencloud.services.search.v0.AggregationResult
|
||||
9, // 8: opencloud.services.search.v0.AggregationOption.bucket_definition:type_name -> opencloud.services.search.v0.BucketDefinition
|
||||
8, // 9: opencloud.services.search.v0.AggregationOption.metric_definition:type_name -> opencloud.services.search.v0.MetricDefinition
|
||||
0, // 10: opencloud.services.search.v0.MetricDefinition.kind:type_name -> opencloud.services.search.v0.MetricKind
|
||||
1, // 11: opencloud.services.search.v0.BucketDefinition.sort_by:type_name -> opencloud.services.search.v0.BucketSortBy
|
||||
10, // 12: opencloud.services.search.v0.BucketDefinition.ranges:type_name -> opencloud.services.search.v0.BucketRange
|
||||
13, // 13: opencloud.services.search.v0.AggregationResult.buckets:type_name -> opencloud.services.search.v0.Bucket
|
||||
12, // 14: opencloud.services.search.v0.AggregationResult.metric:type_name -> opencloud.services.search.v0.Metric
|
||||
0, // 15: opencloud.services.search.v0.Metric.kind:type_name -> opencloud.services.search.v0.MetricKind
|
||||
18, // 16: opencloud.services.search.v0.IndexSpaceResponse.space_duration:type_name -> google.protobuf.Duration
|
||||
2, // 17: opencloud.services.search.v0.IndexSpaceResponse.status:type_name -> opencloud.services.search.v0.IndexSpaceResponse.Status
|
||||
3, // 18: opencloud.services.search.v0.SearchProvider.Search:input_type -> opencloud.services.search.v0.SearchRequest
|
||||
14, // 19: opencloud.services.search.v0.SearchProvider.IndexSpace:input_type -> opencloud.services.search.v0.IndexSpaceRequest
|
||||
5, // 20: opencloud.services.search.v0.IndexProvider.Search:input_type -> opencloud.services.search.v0.SearchIndexRequest
|
||||
4, // 21: opencloud.services.search.v0.SearchProvider.Search:output_type -> opencloud.services.search.v0.SearchResponse
|
||||
15, // 22: opencloud.services.search.v0.SearchProvider.IndexSpace:output_type -> opencloud.services.search.v0.IndexSpaceResponse
|
||||
6, // 23: opencloud.services.search.v0.IndexProvider.Search:output_type -> opencloud.services.search.v0.SearchIndexResponse
|
||||
21, // [21:24] is the sub-list for method output_type
|
||||
18, // [18:21] is the sub-list for method input_type
|
||||
18, // [18:18] is the sub-list for extension type_name
|
||||
18, // [18:18] is the sub-list for extension extendee
|
||||
0, // [0:18] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_opencloud_services_search_v0_search_proto_init() }
|
||||
@@ -1289,7 +1549,7 @@ func file_opencloud_services_search_v0_search_proto_init() {
|
||||
}
|
||||
}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BucketDefinition); i {
|
||||
switch v := v.(*MetricDefinition); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -1301,7 +1561,7 @@ func file_opencloud_services_search_v0_search_proto_init() {
|
||||
}
|
||||
}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BucketRange); i {
|
||||
switch v := v.(*BucketDefinition); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -1313,7 +1573,7 @@ func file_opencloud_services_search_v0_search_proto_init() {
|
||||
}
|
||||
}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AggregationResult); i {
|
||||
switch v := v.(*BucketRange); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -1325,7 +1585,7 @@ func file_opencloud_services_search_v0_search_proto_init() {
|
||||
}
|
||||
}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Bucket); i {
|
||||
switch v := v.(*AggregationResult); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -1337,7 +1597,7 @@ func file_opencloud_services_search_v0_search_proto_init() {
|
||||
}
|
||||
}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*IndexSpaceRequest); i {
|
||||
switch v := v.(*Metric); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -1349,6 +1609,30 @@ func file_opencloud_services_search_v0_search_proto_init() {
|
||||
}
|
||||
}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Bucket); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*IndexSpaceRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*IndexSpaceResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1363,13 +1647,14 @@ func file_opencloud_services_search_v0_search_proto_init() {
|
||||
}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[0].OneofWrappers = []interface{}{}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[2].OneofWrappers = []interface{}{}
|
||||
file_opencloud_services_search_v0_search_proto_msgTypes[9].OneofWrappers = []interface{}{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_opencloud_services_search_v0_search_proto_rawDesc,
|
||||
NumEnums: 2,
|
||||
NumMessages: 11,
|
||||
NumEnums: 3,
|
||||
NumMessages: 13,
|
||||
NumExtensions: 0,
|
||||
NumServices: 2,
|
||||
},
|
||||
|
||||
@@ -172,16 +172,20 @@
|
||||
"properties": {
|
||||
"field": {
|
||||
"type": "string",
|
||||
"description": "Required. The indexed field to aggregate on."
|
||||
"description": "Required. The indexed field to aggregate on (for terms/range\naggregations) or to reduce (for metric aggregations)."
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Optional. Maximum number of buckets to return for a terms aggregation,\napplied after the cross-space merge. 0 returns every bucket. Ignored for\nrange aggregations."
|
||||
"description": "Optional. Maximum number of buckets to return for a terms aggregation,\napplied after the cross-space merge. 0 returns every bucket. Ignored for\nrange and metric aggregations."
|
||||
},
|
||||
"bucketDefinition": {
|
||||
"$ref": "#/definitions/v0BucketDefinition",
|
||||
"description": "Optional. Controls bucket selection, ordering and filtering."
|
||||
"description": "Optional. Controls bucket selection, ordering and filtering.\nIgnored for metric aggregations."
|
||||
},
|
||||
"metricDefinition": {
|
||||
"$ref": "#/definitions/v0MetricDefinition",
|
||||
"description": "Optional. When set, this aggregation is a scalar metric over `field`\nrather than a bucket aggregation; the corresponding AggregationResult\ncarries `metric` instead of `buckets`."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -196,6 +200,10 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/v0Bucket"
|
||||
}
|
||||
},
|
||||
"metric": {
|
||||
"$ref": "#/definitions/v0Metric",
|
||||
"description": "Result of a metric aggregation (metric_definition set on the\ncorresponding AggregationOption). Unset for terms/range aggregations."
|
||||
}
|
||||
},
|
||||
"description": "One result per AggregationOption, at the same position."
|
||||
@@ -535,6 +543,56 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0Metric": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"$ref": "#/definitions/v0MetricKind",
|
||||
"description": "Echoes the kind of the corresponding MetricDefinition."
|
||||
},
|
||||
"value": {
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"description": "The reduced value. Set by the service layer after the cross-space\nmerge, unset when no match carries a value."
|
||||
},
|
||||
"sum": {
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"description": "Accumulators over the values of all matches. An engine fills all of\nthem, whatever the kind, so the service layer can merge results across\nspaces without knowing the kind (an average of averages is no average)."
|
||||
},
|
||||
"count": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
},
|
||||
"min": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"max": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0MetricDefinition": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"$ref": "#/definitions/v0MetricKind"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0MetricKind": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"METRIC_KIND_UNSPECIFIED",
|
||||
"METRIC_KIND_SUM",
|
||||
"METRIC_KIND_MIN",
|
||||
"METRIC_KIND_MAX",
|
||||
"METRIC_KIND_AVG"
|
||||
],
|
||||
"default": "METRIC_KIND_UNSPECIFIED"
|
||||
},
|
||||
"v0MotionPhoto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -124,14 +124,32 @@ message SearchIndexResponse {
|
||||
}
|
||||
|
||||
message AggregationOption {
|
||||
// Required. The indexed field to aggregate on.
|
||||
// Required. The indexed field to aggregate on (for terms/range
|
||||
// aggregations) or to reduce (for metric aggregations).
|
||||
string field = 1;
|
||||
// Optional. Maximum number of buckets to return for a terms aggregation,
|
||||
// applied after the cross-space merge. 0 returns every bucket. Ignored for
|
||||
// range aggregations.
|
||||
// range and metric aggregations.
|
||||
int32 size = 2 [(google.api.field_behavior) = OPTIONAL];
|
||||
// Optional. Controls bucket selection, ordering and filtering.
|
||||
// Ignored for metric aggregations.
|
||||
BucketDefinition bucket_definition = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||
// Optional. When set, this aggregation is a scalar metric over `field`
|
||||
// rather than a bucket aggregation; the corresponding AggregationResult
|
||||
// carries `metric` instead of `buckets`.
|
||||
MetricDefinition metric_definition = 4 [(google.api.field_behavior) = OPTIONAL];
|
||||
}
|
||||
|
||||
message MetricDefinition {
|
||||
MetricKind kind = 1;
|
||||
}
|
||||
|
||||
enum MetricKind {
|
||||
METRIC_KIND_UNSPECIFIED = 0;
|
||||
METRIC_KIND_SUM = 1;
|
||||
METRIC_KIND_MIN = 2;
|
||||
METRIC_KIND_MAX = 3;
|
||||
METRIC_KIND_AVG = 4;
|
||||
}
|
||||
|
||||
message BucketDefinition {
|
||||
@@ -164,6 +182,24 @@ message BucketRange {
|
||||
message AggregationResult {
|
||||
string field = 1;
|
||||
repeated Bucket buckets = 2;
|
||||
// Result of a metric aggregation (metric_definition set on the
|
||||
// corresponding AggregationOption). Unset for terms/range aggregations.
|
||||
Metric metric = 3;
|
||||
}
|
||||
|
||||
message Metric {
|
||||
// Echoes the kind of the corresponding MetricDefinition.
|
||||
MetricKind kind = 1;
|
||||
// The reduced value. Set by the service layer after the cross-space
|
||||
// merge, unset when no match carries a value.
|
||||
optional double value = 2;
|
||||
// Accumulators over the values of all matches. An engine fills all of
|
||||
// them, whatever the kind, so the service layer can merge results across
|
||||
// spaces without knowing the kind (an average of averages is no average).
|
||||
double sum = 3;
|
||||
int64 count = 4;
|
||||
double min = 5;
|
||||
double max = 6;
|
||||
}
|
||||
|
||||
message Bucket {
|
||||
|
||||
@@ -98,8 +98,6 @@ func unsupportedProperty(sr libregraph.SearchRequest) string {
|
||||
return "@libre.graph.geohashDefinition"
|
||||
case len(a.LibreGraphSubAggregations) > 0:
|
||||
return "@libre.graph.subAggregations"
|
||||
case a.LibreGraphMetricDefinition != nil:
|
||||
return "@libre.graph.metricDefinition"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
@@ -218,17 +216,25 @@ func validatePagination(fromP, sizeP *int32) error {
|
||||
return search.CheckResultWindow(from, size)
|
||||
}
|
||||
|
||||
// openapi-generator enforces neither the enums nor the bounds of the spec.
|
||||
// Whether an aggregation fits its field is for aggregation.ValidateOptions to
|
||||
// say.
|
||||
// openapi-generator enforces neither the enums and bounds of the spec nor its
|
||||
// at-most-one definition rule. Whether an aggregation fits its field is for
|
||||
// aggregation.ValidateOptions to say.
|
||||
func validateAggregations(aggs []libregraph.AggregationOption) error {
|
||||
for _, a := range aggs {
|
||||
if a.Field == "" {
|
||||
return fmt.Errorf("aggregation field must not be empty")
|
||||
}
|
||||
if a.BucketDefinition != nil && a.LibreGraphMetricDefinition != nil {
|
||||
return fmt.Errorf("aggregation on %q sets more than one of bucketDefinition and @libre.graph.metricDefinition", a.Field)
|
||||
}
|
||||
if a.Size != nil && *a.Size < 1 {
|
||||
return fmt.Errorf("size of the aggregation on %q must be at least 1", a.Field)
|
||||
}
|
||||
if md := a.LibreGraphMetricDefinition; md != nil {
|
||||
if _, ok := metricKinds[md.Kind]; !ok {
|
||||
return fmt.Errorf("unsupported metric kind %q on field %q", md.Kind, a.Field)
|
||||
}
|
||||
}
|
||||
if bd := a.BucketDefinition; bd != nil {
|
||||
if _, ok := bucketSortBy[bd.SortBy]; !ok {
|
||||
return fmt.Errorf("unsupported sortBy %q on field %q", bd.SortBy, a.Field)
|
||||
|
||||
@@ -21,6 +21,13 @@ var bucketSortBy = map[string]searchsvc.BucketSortBy{
|
||||
"keyAsNumber": searchsvc.BucketSortBy_BUCKET_SORT_BY_KEY_AS_NUMBER,
|
||||
}
|
||||
|
||||
var metricKinds = map[string]searchsvc.MetricKind{
|
||||
"sum": searchsvc.MetricKind_METRIC_KIND_SUM,
|
||||
"min": searchsvc.MetricKind_METRIC_KIND_MIN,
|
||||
"max": searchsvc.MetricKind_METRIC_KIND_MAX,
|
||||
"avg": searchsvc.MetricKind_METRIC_KIND_AVG,
|
||||
}
|
||||
|
||||
// driveItemFields are the scalar driveItem properties a hit carries and the
|
||||
// index fields behind them; a facet property (audio.artist) is its index
|
||||
// field already.
|
||||
@@ -61,6 +68,9 @@ func libregraphAggregationsToSearch(in []libregraph.AggregationOption) []*search
|
||||
if a.BucketDefinition != nil {
|
||||
agg.BucketDefinition = libregraphBucketDefinitionToSearch(*a.BucketDefinition)
|
||||
}
|
||||
if md := a.LibreGraphMetricDefinition; md != nil {
|
||||
agg.MetricDefinition = &searchsvc.MetricDefinition{Kind: metricKinds[md.Kind]}
|
||||
}
|
||||
out = append(out, agg)
|
||||
}
|
||||
return out
|
||||
@@ -101,6 +111,15 @@ func searchAggregationsToLibregraph(in []*searchsvc.AggregationResult, defs []li
|
||||
break
|
||||
}
|
||||
agg := libregraph.SearchAggregation{Field: libregraph.PtrString(def.Field)}
|
||||
if md := def.LibreGraphMetricDefinition; md != nil {
|
||||
agg.LibreGraphMetric = &libregraph.SearchMetric{Kind: libregraph.PtrString(md.Kind)}
|
||||
// a metric without a single value has no value
|
||||
if m := in[i].GetMetric(); m != nil {
|
||||
agg.LibreGraphMetric.Value = m.Value
|
||||
}
|
||||
out = append(out, agg)
|
||||
continue
|
||||
}
|
||||
agg.Buckets = make([]libregraph.SearchBucket, 0, len(in[i].GetBuckets()))
|
||||
for _, b := range in[i].GetBuckets() {
|
||||
agg.Buckets = append(agg.Buckets, libregraph.SearchBucket{
|
||||
|
||||
@@ -86,7 +86,11 @@ func oneMatch(entity *searchmsg.Entity) *searchsvc.SearchResponse {
|
||||
}
|
||||
|
||||
type searchAggregationJSON struct {
|
||||
Field string `json:"field"`
|
||||
Field string `json:"field"`
|
||||
Metric *struct {
|
||||
Kind string `json:"kind"`
|
||||
Value *float64 `json:"value"`
|
||||
} `json:"@libre.graph.metric"`
|
||||
Buckets []struct {
|
||||
Key string `json:"key"`
|
||||
Count int64 `json:"count"`
|
||||
@@ -299,6 +303,9 @@ var _ = ginkgo.Describe("SearchQuery", func() {
|
||||
Expect(rr.Body.String()).To(ContainSubstring("invalidRequest"))
|
||||
},
|
||||
ginkgo.Entry("an empty field", `"aggregations": [{"field": ""}]`),
|
||||
ginkgo.Entry("a bucket and a metric definition at once",
|
||||
`"aggregations": [{"field": "audio.year", "bucketDefinition": {"sortBy": "count", "ranges": [{"from": "1980"}]}, "@libre.graph.metricDefinition": {"kind": "sum"}}]`),
|
||||
ginkgo.Entry("an unknown metric kind", `"aggregations": [{"field": "audio.year", "@libre.graph.metricDefinition": {"kind": "median"}}]`),
|
||||
ginkgo.Entry("an unknown sortBy", `"aggregations": [{"field": "audio.artist", "bucketDefinition": {"sortBy": "relevance"}}]`),
|
||||
ginkgo.Entry("a size below one", `"aggregations": [{"field": "audio.artist", "size": 0}]`),
|
||||
ginkgo.Entry("a negative minimumCount", `"aggregations": [{"field": "audio.artist", "bucketDefinition": {"sortBy": "count", "minimumCount": -1}}]`),
|
||||
@@ -368,6 +375,27 @@ var _ = ginkgo.Describe("SearchQuery", func() {
|
||||
Expect(hitsContainer(rr).Aggregations[0].Field).To(Equal("lastModifiedDateTime"))
|
||||
})
|
||||
|
||||
ginkgo.It("maps a metric result, without a value when the metric has none", func() {
|
||||
value := 1986.5
|
||||
g, captured := graphWithAggregations(
|
||||
&searchsvc.AggregationResult{Field: "audio.year", Metric: &searchsvc.Metric{Kind: searchsvc.MetricKind_METRIC_KIND_AVG, Value: &value, Sum: 3973, Count: 2}},
|
||||
&searchsvc.AggregationResult{Field: "audio.year", Metric: &searchsvc.Metric{Kind: searchsvc.MetricKind_METRIC_KIND_MIN}},
|
||||
)
|
||||
rr := postSearchQuery(g, searchQueryBody(`"aggregations": [
|
||||
{"field": "audio.year", "@libre.graph.metricDefinition": {"kind": "avg"}},
|
||||
{"field": "audio.year", "@libre.graph.metricDefinition": {"kind": "min"}}
|
||||
]`))
|
||||
Expect(rr.Code).To(Equal(http.StatusOK), rr.Body.String())
|
||||
Expect(captured().GetAggregations()[0].GetMetricDefinition().GetKind()).To(Equal(searchsvc.MetricKind_METRIC_KIND_AVG))
|
||||
|
||||
aggs := hitsContainer(rr).Aggregations
|
||||
Expect(aggs).To(HaveLen(2))
|
||||
Expect(aggs[0].Metric.Kind).To(Equal("avg"))
|
||||
Expect(aggs[0].Metric.Value).To(HaveValue(Equal(1986.5)))
|
||||
Expect(aggs[1].Metric.Kind).To(Equal("min"))
|
||||
Expect(aggs[1].Metric.Value).To(BeNil(), "no value, not zero")
|
||||
})
|
||||
|
||||
ginkgo.DescribeTable("answers a property it does not evaluate with 501 instead of ignoring it",
|
||||
func(fragment, property string) {
|
||||
rr := postSearchQuery(graphWithoutSearch(), searchQueryBody(fragment))
|
||||
@@ -379,7 +407,6 @@ var _ = ginkgo.Describe("SearchQuery", func() {
|
||||
ginkgo.Entry("aggregationFilters", `"aggregationFilters": ["audio.artist:\"ǂǂ5361786f6e\""]`, "aggregationFilters"),
|
||||
ginkgo.Entry("a geohash aggregation",
|
||||
`"aggregations": [{"field": "location", "@libre.graph.geohashDefinition": {"precision": 5}}]`, "geohashDefinition"),
|
||||
ginkgo.Entry("a metric", `"aggregations": [{"field": "audio.year", "@libre.graph.metricDefinition": {"kind": "sum"}}]`, "metricDefinition"),
|
||||
ginkgo.Entry("sub-aggregations", `"aggregations": [{"field": "audio.artist", "@libre.graph.subAggregations": [{"field": "audio.album"}]}]`, "subAggregations"),
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Package aggregation holds what the engines and the service layer share
|
||||
// about aggregations: the kind of an option, range bounds and the cross-space
|
||||
// merge.
|
||||
// about aggregations: the kind of an option, range bounds, metric
|
||||
// accumulators and the cross-space merge.
|
||||
package aggregation
|
||||
|
||||
import (
|
||||
@@ -17,11 +17,15 @@ type Kind int
|
||||
const (
|
||||
KindTerms Kind = iota
|
||||
KindRange
|
||||
KindMetric
|
||||
)
|
||||
|
||||
// KindOf tells the kind from the definitions an option carries.
|
||||
func KindOf(opt *searchsvc.AggregationOption) Kind {
|
||||
if len(opt.GetBucketDefinition().GetRanges()) > 0 {
|
||||
switch {
|
||||
case opt.GetMetricDefinition() != nil:
|
||||
return KindMetric
|
||||
case len(opt.GetBucketDefinition().GetRanges()) > 0:
|
||||
return KindRange
|
||||
}
|
||||
return KindTerms
|
||||
|
||||
@@ -18,7 +18,10 @@ func Empty(opts []*searchsvc.AggregationOption) []*searchsvc.AggregationResult {
|
||||
out := make([]*searchsvc.AggregationResult, len(opts))
|
||||
for i, opt := range opts {
|
||||
out[i] = &searchsvc.AggregationResult{Field: opt.GetField()}
|
||||
if KindOf(opt) == KindRange {
|
||||
switch KindOf(opt) {
|
||||
case KindMetric:
|
||||
out[i].Metric = &searchsvc.Metric{Kind: opt.GetMetricDefinition().GetKind()}
|
||||
case KindRange:
|
||||
out[i].Buckets = RangeBuckets(opt, nil)
|
||||
}
|
||||
}
|
||||
@@ -47,10 +50,14 @@ func Merge(opts []*searchsvc.AggregationOption, acc, results []*searchsvc.Aggreg
|
||||
if acc == nil {
|
||||
acc = Empty(opts)
|
||||
}
|
||||
for i := range opts {
|
||||
for i, opt := range opts {
|
||||
if i >= len(results) || results[i] == nil {
|
||||
continue
|
||||
}
|
||||
if KindOf(opt) == KindMetric {
|
||||
add(acc[i].GetMetric(), results[i].GetMetric())
|
||||
continue
|
||||
}
|
||||
byKey := make(map[string]*searchsvc.Bucket, len(acc[i].GetBuckets()))
|
||||
for _, b := range acc[i].GetBuckets() {
|
||||
byKey[b.GetKey()] = b
|
||||
@@ -69,10 +76,17 @@ func Merge(opts []*searchsvc.AggregationOption, acc, results []*searchsvc.Aggreg
|
||||
}
|
||||
|
||||
// Finalize shapes merged results per their options: buckets get their minimum
|
||||
// count, order and size.
|
||||
// count, order and size, metrics their value.
|
||||
func Finalize(opts []*searchsvc.AggregationOption, results []*searchsvc.AggregationResult) {
|
||||
for i, opt := range opts {
|
||||
results[i].Buckets = shapeBuckets(opt, results[i].GetBuckets())
|
||||
r := results[i]
|
||||
if KindOf(opt) == KindMetric {
|
||||
if v, ok := MetricValue(r.GetMetric()); ok {
|
||||
r.Metric.Value = &v
|
||||
}
|
||||
continue
|
||||
}
|
||||
r.Buckets = shapeBuckets(opt, r.GetBuckets())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package aggregation_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
@@ -10,6 +11,22 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/services/search/pkg/aggregation"
|
||||
)
|
||||
|
||||
func metricOpt(field string, kind searchsvc.MetricKind) *searchsvc.AggregationOption {
|
||||
return &searchsvc.AggregationOption{Field: field, MetricDefinition: &searchsvc.MetricDefinition{Kind: kind}}
|
||||
}
|
||||
|
||||
// metric is what an engine answers for the given values: all accumulators.
|
||||
func metric(field string, kind searchsvc.MetricKind, values ...float64) *searchsvc.AggregationResult {
|
||||
m := &searchsvc.Metric{Kind: kind, Count: int64(len(values))}
|
||||
if len(values) > 0 {
|
||||
m.Min, m.Max = slices.Min(values), slices.Max(values)
|
||||
}
|
||||
for _, v := range values {
|
||||
m.Sum += v
|
||||
}
|
||||
return &searchsvc.AggregationResult{Field: field, Metric: m}
|
||||
}
|
||||
|
||||
func buckets(field string, bs ...*searchsvc.Bucket) *searchsvc.AggregationResult {
|
||||
return &searchsvc.AggregationResult{Field: field, Buckets: bs}
|
||||
}
|
||||
@@ -22,10 +39,19 @@ func rangesOf(sortBy searchsvc.BucketSortBy, rs ...*searchsvc.BucketRange) *sear
|
||||
return &searchsvc.BucketDefinition{SortBy: sortBy, Ranges: rs}
|
||||
}
|
||||
|
||||
// render flattens results like the parity suite: one line per bucket.
|
||||
// render flattens results like the parity suite: one line per bucket or
|
||||
// metric.
|
||||
func render(results []*searchsvc.AggregationResult) []string {
|
||||
out := []string{}
|
||||
for _, r := range results {
|
||||
if m := r.GetMetric(); m != nil {
|
||||
if m.Value == nil {
|
||||
out = append(out, fmt.Sprintf("%s %s none", r.GetField(), m.GetKind()))
|
||||
} else {
|
||||
out = append(out, fmt.Sprintf("%s %s=%v", r.GetField(), m.GetKind(), m.GetValue()))
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, b := range r.GetBuckets() {
|
||||
out = append(out, fmt.Sprintf("%s %s=%d", r.GetField(), b.GetKey(), b.GetCount()))
|
||||
}
|
||||
@@ -44,16 +70,27 @@ func merged(opts []*searchsvc.AggregationOption, spaces ...[]*searchsvc.Aggregat
|
||||
}
|
||||
|
||||
var _ = Describe("Merge and Finalize", func() {
|
||||
const (
|
||||
sum = searchsvc.MetricKind_METRIC_KIND_SUM
|
||||
min = searchsvc.MetricKind_METRIC_KIND_MIN
|
||||
max = searchsvc.MetricKind_METRIC_KIND_MAX
|
||||
avg = searchsvc.MetricKind_METRIC_KIND_AVG
|
||||
)
|
||||
|
||||
It("answers one result per option without any space, every range at zero", func() {
|
||||
opts := []*searchsvc.AggregationOption{
|
||||
{Field: "audio.artist"},
|
||||
metricOpt("audio.year", sum),
|
||||
{Field: "audio.year", BucketDefinition: rangesOf(searchsvc.BucketSortBy_BUCKET_SORT_BY_KEY_AS_NUMBER, &searchsvc.BucketRange{To: "1980"}, &searchsvc.BucketRange{From: "1980"})},
|
||||
}
|
||||
got := merged(opts)
|
||||
Expect(got).To(HaveLen(2))
|
||||
Expect(got).To(HaveLen(3))
|
||||
Expect(got[0].GetField()).To(Equal("audio.artist"))
|
||||
Expect(got[0].GetBuckets()).To(BeEmpty())
|
||||
Expect(render(got)).To(Equal([]string{"audio.year ..1980=0", "audio.year 1980..=0"}))
|
||||
Expect(render(got)).To(Equal([]string{
|
||||
"audio.year METRIC_KIND_SUM none",
|
||||
"audio.year ..1980=0", "audio.year 1980..=0",
|
||||
}))
|
||||
})
|
||||
|
||||
It("adds up the counts of a bucket across spaces", func() {
|
||||
@@ -66,10 +103,11 @@ var _ = Describe("Merge and Finalize", func() {
|
||||
})
|
||||
|
||||
It("leaves the answers of the spaces untouched", func() {
|
||||
opts := []*searchsvc.AggregationOption{{Field: "audio.artist"}}
|
||||
space := []*searchsvc.AggregationResult{buckets("audio.artist", bucket("Saxon", 2))}
|
||||
opts := []*searchsvc.AggregationOption{{Field: "audio.artist"}, metricOpt("audio.year", sum)}
|
||||
space := []*searchsvc.AggregationResult{buckets("audio.artist", bucket("Saxon", 2)), metric("audio.year", sum, 1980)}
|
||||
merged(opts, space, space)
|
||||
Expect(space[0].GetBuckets()[0].GetCount()).To(Equal(int64(2)))
|
||||
Expect(space[1].GetMetric().GetSum()).To(Equal(1980.0))
|
||||
})
|
||||
|
||||
It("keeps two terms aggregations on one field apart", func() {
|
||||
@@ -84,24 +122,46 @@ var _ = Describe("Merge and Finalize", func() {
|
||||
}))
|
||||
})
|
||||
|
||||
It("keeps two range aggregations on one field apart", func() {
|
||||
It("keeps range and metric aggregations on one field apart", func() {
|
||||
opts := []*searchsvc.AggregationOption{
|
||||
{Field: "audio.year", BucketDefinition: rangesOf(searchsvc.BucketSortBy_BUCKET_SORT_BY_KEY_AS_NUMBER, &searchsvc.BucketRange{To: "1980"}, &searchsvc.BucketRange{From: "1980"})},
|
||||
metricOpt("audio.year", min),
|
||||
{Field: "audio.year", BucketDefinition: rangesOf(searchsvc.BucketSortBy_BUCKET_SORT_BY_KEY_AS_NUMBER, &searchsvc.BucketRange{To: "2000"}, &searchsvc.BucketRange{From: "2000"})},
|
||||
metricOpt("audio.year", max),
|
||||
}
|
||||
space := func(below1980, from1980, below2000, from2000 int64) []*searchsvc.AggregationResult {
|
||||
space := func(below1980, from1980, below2000, from2000 int64, years ...float64) []*searchsvc.AggregationResult {
|
||||
return []*searchsvc.AggregationResult{
|
||||
buckets("audio.year", bucket("..1980", below1980), bucket("1980..", from1980)),
|
||||
metric("audio.year", min, years...),
|
||||
buckets("audio.year", bucket("..2000", below2000), bucket("2000..", from2000)),
|
||||
metric("audio.year", max, years...),
|
||||
}
|
||||
}
|
||||
got := merged(opts, space(1, 1, 2, 0), space(0, 2, 1, 1))
|
||||
got := merged(opts, space(1, 1, 2, 0, 1971, 1982), space(0, 2, 1, 1, 1999, 2001))
|
||||
Expect(render(got)).To(Equal([]string{
|
||||
"audio.year ..1980=1", "audio.year 1980..=3",
|
||||
"audio.year METRIC_KIND_MIN=1971",
|
||||
"audio.year ..2000=3", "audio.year 2000..=1",
|
||||
"audio.year METRIC_KIND_MAX=2001",
|
||||
}))
|
||||
})
|
||||
|
||||
DescribeTable("reduces a metric over the values of all spaces",
|
||||
func(kind searchsvc.MetricKind, want string) {
|
||||
opts := []*searchsvc.AggregationOption{metricOpt("audio.year", kind)}
|
||||
got := merged(opts,
|
||||
[]*searchsvc.AggregationResult{metric("audio.year", kind, 1970, 1980, 1990)},
|
||||
[]*searchsvc.AggregationResult{metric("audio.year", kind)},
|
||||
[]*searchsvc.AggregationResult{metric("audio.year", kind, 2010)},
|
||||
)
|
||||
Expect(render(got)).To(Equal([]string{"audio.year " + want}))
|
||||
},
|
||||
Entry("sum", sum, "METRIC_KIND_SUM=7950"),
|
||||
Entry("min, a space without values is no zero", min, "METRIC_KIND_MIN=1970"),
|
||||
Entry("max", max, "METRIC_KIND_MAX=2010"),
|
||||
Entry("avg of the values, not of the averages of the spaces", avg, "METRIC_KIND_AVG=1987.5"),
|
||||
)
|
||||
|
||||
Describe("bucket order", func() {
|
||||
space := []*searchsvc.AggregationResult{buckets("audio.track",
|
||||
bucket("10", 2), bucket("9", 2), bucket("2", 5), bucket("b-side", 1),
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package aggregation
|
||||
|
||||
import (
|
||||
searchsvc "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/search/v0"
|
||||
)
|
||||
|
||||
// Observe adds a field value to the accumulators of m.
|
||||
func Observe(m *searchsvc.Metric, v float64) {
|
||||
add(m, &searchsvc.Metric{Sum: v, Count: 1, Min: v, Max: v})
|
||||
}
|
||||
|
||||
func add(into, from *searchsvc.Metric) {
|
||||
if from.GetCount() == 0 {
|
||||
return
|
||||
}
|
||||
if into.GetCount() == 0 {
|
||||
into.Min, into.Max = from.GetMin(), from.GetMax()
|
||||
} else {
|
||||
into.Min, into.Max = min(into.GetMin(), from.GetMin()), max(into.GetMax(), from.GetMax())
|
||||
}
|
||||
into.Sum += from.GetSum()
|
||||
into.Count += from.GetCount()
|
||||
}
|
||||
|
||||
// MetricValue reduces the accumulators to the value of the metric's kind;
|
||||
// there is none without a single observed value.
|
||||
func MetricValue(m *searchsvc.Metric) (float64, bool) {
|
||||
if m.GetCount() == 0 {
|
||||
return 0, false
|
||||
}
|
||||
switch m.GetKind() {
|
||||
case searchsvc.MetricKind_METRIC_KIND_SUM:
|
||||
return m.GetSum(), true
|
||||
case searchsvc.MetricKind_METRIC_KIND_MIN:
|
||||
return m.GetMin(), true
|
||||
case searchsvc.MetricKind_METRIC_KIND_MAX:
|
||||
return m.GetMax(), true
|
||||
case searchsvc.MetricKind_METRIC_KIND_AVG:
|
||||
return m.GetSum() / float64(m.GetCount()), true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package aggregation_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
searchsvc "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/search/v0"
|
||||
"github.com/opencloud-eu/opencloud/services/search/pkg/aggregation"
|
||||
)
|
||||
|
||||
var _ = Describe("Observe", func() {
|
||||
It("keeps every accumulator, whatever the kind", func() {
|
||||
m := &searchsvc.Metric{Kind: searchsvc.MetricKind_METRIC_KIND_MAX}
|
||||
for _, v := range []float64{1982, 1971, 2001} {
|
||||
aggregation.Observe(m, v)
|
||||
}
|
||||
Expect(m.GetCount()).To(Equal(int64(3)))
|
||||
Expect(m.GetSum()).To(Equal(5954.0))
|
||||
Expect(m.GetMin()).To(Equal(1971.0))
|
||||
Expect(m.GetMax()).To(Equal(2001.0))
|
||||
Expect(m.Value).To(BeNil())
|
||||
})
|
||||
|
||||
It("takes the first value as minimum and maximum, a negative one too", func() {
|
||||
m := &searchsvc.Metric{}
|
||||
aggregation.Observe(m, -3)
|
||||
Expect(m.GetMin()).To(Equal(-3.0))
|
||||
Expect(m.GetMax()).To(Equal(-3.0))
|
||||
})
|
||||
})
|
||||
@@ -17,6 +17,10 @@ func ValidateOptions(opts []*searchsvc.AggregationOption, fieldType func(string)
|
||||
return fmt.Errorf("unknown aggregation field %q", field)
|
||||
}
|
||||
switch KindOf(opt) {
|
||||
case KindMetric:
|
||||
if t != mapping.TypeNumeric {
|
||||
return fmt.Errorf("metric aggregation needs a numeric field, %q is none", field)
|
||||
}
|
||||
case KindRange:
|
||||
parsed, err := ParseRanges(field, opt.GetBucketDefinition().GetRanges())
|
||||
if err != nil {
|
||||
|
||||
@@ -27,6 +27,7 @@ func fieldTypes(field string) string {
|
||||
var _ = Describe("ValidateOptions", func() {
|
||||
numeric := &searchsvc.BucketDefinition{Ranges: []*searchsvc.BucketRange{{From: "1980", To: "1990"}}}
|
||||
dates := &searchsvc.BucketDefinition{Ranges: []*searchsvc.BucketRange{{From: "2018-08-11T00:00:00Z"}}}
|
||||
sum := &searchsvc.MetricDefinition{Kind: searchsvc.MetricKind_METRIC_KIND_SUM}
|
||||
|
||||
DescribeTable("accepts an aggregation that fits its field",
|
||||
func(opt *searchsvc.AggregationOption) {
|
||||
@@ -37,6 +38,7 @@ var _ = Describe("ValidateOptions", func() {
|
||||
Entry("terms on a number", &searchsvc.AggregationOption{Field: "audio.year"}),
|
||||
Entry("numeric ranges on a number", &searchsvc.AggregationOption{Field: "audio.year", BucketDefinition: numeric}),
|
||||
Entry("date ranges on a date", &searchsvc.AggregationOption{Field: "photo.takenDateTime", BucketDefinition: dates}),
|
||||
Entry("a metric on a number", &searchsvc.AggregationOption{Field: "audio.year", MetricDefinition: sum}),
|
||||
)
|
||||
|
||||
DescribeTable("rejects an aggregation the index cannot answer",
|
||||
@@ -49,6 +51,8 @@ var _ = Describe("ValidateOptions", func() {
|
||||
Entry("terms on a path", &searchsvc.AggregationOption{Field: "Path"}),
|
||||
Entry("terms on a facet object", &searchsvc.AggregationOption{Field: "audio"}),
|
||||
Entry("terms on a geopoint", &searchsvc.AggregationOption{Field: "location"}),
|
||||
Entry("a metric on a keyword", &searchsvc.AggregationOption{Field: "audio.artist", MetricDefinition: sum}),
|
||||
Entry("a metric on a date", &searchsvc.AggregationOption{Field: "photo.takenDateTime", MetricDefinition: sum}),
|
||||
Entry("numeric ranges on a keyword", &searchsvc.AggregationOption{Field: "audio.artist", BucketDefinition: numeric}),
|
||||
Entry("numeric ranges on a date", &searchsvc.AggregationOption{Field: "photo.takenDateTime", BucketDefinition: numeric}),
|
||||
Entry("date ranges on a number", &searchsvc.AggregationOption{Field: "audio.year", BucketDefinition: dates}),
|
||||
|
||||
@@ -69,9 +69,13 @@ type fieldValues struct {
|
||||
|
||||
type bucketAcc struct {
|
||||
counts map[string]int64
|
||||
metric *searchService.Metric
|
||||
}
|
||||
|
||||
func newBucketAcc() *bucketAcc {
|
||||
func newBucketAcc(l *aggLevel) *bucketAcc {
|
||||
if l.kind == aggregation.KindMetric {
|
||||
return &bucketAcc{metric: &searchService.Metric{Kind: l.opt.GetMetricDefinition().GetKind()}}
|
||||
}
|
||||
return &bucketAcc{counts: map[string]int64{}}
|
||||
}
|
||||
|
||||
@@ -98,7 +102,7 @@ func newAggCollector(aggs []*searchService.AggregationOption) (*aggCollector, er
|
||||
return nil, err
|
||||
}
|
||||
c.register(l)
|
||||
c.roots = append(c.roots, &aggRoot{level: l, acc: newBucketAcc()})
|
||||
c.roots = append(c.roots, &aggRoot{level: l, acc: newBucketAcc(l)})
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
@@ -180,6 +184,10 @@ func (c *aggCollector) visit(field string, term []byte) {
|
||||
func (c *aggCollector) fold(a *bucketAcc, l *aggLevel) {
|
||||
fv := c.fields[l.opt.GetField()]
|
||||
switch l.kind {
|
||||
case aggregation.KindMetric:
|
||||
for _, raw := range fv.numbers {
|
||||
aggregation.Observe(a.metric, numeric.Int64ToFloat64(raw))
|
||||
}
|
||||
case aggregation.KindTerms:
|
||||
if l.numericTerms() {
|
||||
for _, raw := range fv.numbers {
|
||||
@@ -223,6 +231,10 @@ func (c *aggCollector) results() []*searchService.AggregationResult {
|
||||
|
||||
func (a *bucketAcc) result(l *aggLevel) *searchService.AggregationResult {
|
||||
r := &searchService.AggregationResult{Field: l.opt.GetField()}
|
||||
if l.kind == aggregation.KindMetric {
|
||||
r.Metric = a.metric
|
||||
return r
|
||||
}
|
||||
|
||||
counted := make(map[string]*searchService.Bucket, len(a.counts))
|
||||
for key, count := range a.counts {
|
||||
|
||||
@@ -38,6 +38,10 @@ func aggName(position int) string {
|
||||
func build(opt *searchsvc.AggregationOption) (map[string]any, error) {
|
||||
var entry map[string]any
|
||||
switch aggregation.KindOf(opt) {
|
||||
case aggregation.KindMetric:
|
||||
// all accumulators, whatever the kind: the service layer merges them
|
||||
// across spaces and reduces to the kind's value
|
||||
return map[string]any{"stats": map[string]any{"field": opt.GetField()}}, nil
|
||||
case aggregation.KindRange:
|
||||
ranges, err := buildRanges(opt.GetField(), opt.GetBucketDefinition().GetRanges())
|
||||
if err != nil {
|
||||
@@ -113,6 +117,9 @@ func parse(opts []*searchsvc.AggregationOption, node aggNode) ([]*searchsvc.Aggr
|
||||
}
|
||||
|
||||
func result(opt *searchsvc.AggregationOption, raw json.RawMessage) (*searchsvc.AggregationResult, error) {
|
||||
if aggregation.KindOf(opt) == aggregation.KindMetric {
|
||||
return metricResult(opt, raw)
|
||||
}
|
||||
var body struct {
|
||||
Buckets []json.RawMessage `json:"buckets"`
|
||||
SumOtherDocCount int64 `json:"sum_other_doc_count"`
|
||||
@@ -173,3 +180,29 @@ func bucketKey(key any, asString *string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// metricResult reads a stats aggregation; min and max are null without a
|
||||
// single value.
|
||||
func metricResult(opt *searchsvc.AggregationOption, raw json.RawMessage) (*searchsvc.AggregationResult, error) {
|
||||
res := &searchsvc.AggregationResult{
|
||||
Field: opt.GetField(),
|
||||
Metric: &searchsvc.Metric{Kind: opt.GetMetricDefinition().GetKind()},
|
||||
}
|
||||
if len(raw) == 0 {
|
||||
return res, nil
|
||||
}
|
||||
var body struct {
|
||||
Count int64 `json:"count"`
|
||||
Sum float64 `json:"sum"`
|
||||
Min *float64 `json:"min"`
|
||||
Max *float64 `json:"max"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &body); err != nil {
|
||||
return nil, fmt.Errorf("decode metric aggregation on %s: %w", opt.GetField(), err)
|
||||
}
|
||||
if body.Count == 0 || body.Min == nil || body.Max == nil {
|
||||
return res, nil
|
||||
}
|
||||
res.Metric.Count, res.Metric.Sum, res.Metric.Min, res.Metric.Max = body.Count, body.Sum, *body.Min, *body.Max
|
||||
return res, nil
|
||||
}
|
||||
@@ -123,6 +123,48 @@ var _ = Describe("Aggregations", func() {
|
||||
Expect(keys(out[0])).To(Equal([]string{"1980..1990=0", "1970..1980=4", "1990..=0"}))
|
||||
})
|
||||
|
||||
DescribeTable("asks for all accumulators of a metric, whatever its kind",
|
||||
func(kind searchsvc.MetricKind) {
|
||||
opt := &searchsvc.AggregationOption{Field: "audio.duration", MetricDefinition: &searchsvc.MetricDefinition{Kind: kind}}
|
||||
stats := build(opt)["a_0"].(map[string]any)["stats"].(map[string]any)
|
||||
Expect(stats["field"]).To(Equal("audio.duration"))
|
||||
|
||||
m := parse(`{"a_0": {"count": 100, "min": 30000.0, "max": 500000.0, "avg": 245000.0, "sum": 24500000.0}}`, opt)[0].GetMetric()
|
||||
Expect(m.GetKind()).To(Equal(kind))
|
||||
Expect(m.GetCount()).To(Equal(int64(100)))
|
||||
Expect(m.GetSum()).To(Equal(24500000.0))
|
||||
Expect(m.GetMin()).To(Equal(30000.0))
|
||||
Expect(m.GetMax()).To(Equal(500000.0))
|
||||
Expect(m.Value).To(BeNil(), "the service layer reduces to the value after the merge")
|
||||
},
|
||||
Entry("sum", searchsvc.MetricKind_METRIC_KIND_SUM),
|
||||
Entry("min", searchsvc.MetricKind_METRIC_KIND_MIN),
|
||||
Entry("max", searchsvc.MetricKind_METRIC_KIND_MAX),
|
||||
Entry("avg", searchsvc.MetricKind_METRIC_KIND_AVG),
|
||||
)
|
||||
|
||||
It("leaves a metric without a single value empty instead of reading null as zero", func() {
|
||||
m := parse(`{"a_0": {"count": 0, "min": null, "max": null, "avg": null, "sum": 0.0}}`,
|
||||
&searchsvc.AggregationOption{Field: "audio.duration", MetricDefinition: &searchsvc.MetricDefinition{Kind: searchsvc.MetricKind_METRIC_KIND_MIN}})[0].GetMetric()
|
||||
Expect(m.GetKind()).To(Equal(searchsvc.MetricKind_METRIC_KIND_MIN))
|
||||
Expect(m.GetCount()).To(BeZero())
|
||||
})
|
||||
|
||||
It("answers one result per aggregation, in request order", func() {
|
||||
out := parse(`{}`,
|
||||
&searchsvc.AggregationOption{Field: "audio.year", MetricDefinition: &searchsvc.MetricDefinition{Kind: searchsvc.MetricKind_METRIC_KIND_SUM}},
|
||||
&searchsvc.AggregationOption{Field: "audio.artist"},
|
||||
&searchsvc.AggregationOption{Field: "audio.year", BucketDefinition: &searchsvc.BucketDefinition{Ranges: []*searchsvc.BucketRange{{To: "1980"}}}},
|
||||
&searchsvc.AggregationOption{Field: "audio.year", MetricDefinition: &searchsvc.MetricDefinition{Kind: searchsvc.MetricKind_METRIC_KIND_MAX}},
|
||||
)
|
||||
Expect(out).To(HaveLen(4))
|
||||
Expect(out[0].GetMetric().GetKind()).To(Equal(searchsvc.MetricKind_METRIC_KIND_SUM))
|
||||
Expect(out[1].GetMetric()).To(BeNil())
|
||||
Expect(out[1].GetBuckets()).To(BeEmpty())
|
||||
Expect(keys(out[2])).To(Equal([]string{"..1980=0"}))
|
||||
Expect(out[3].GetMetric().GetKind()).To(Equal(searchsvc.MetricKind_METRIC_KIND_MAX))
|
||||
})
|
||||
|
||||
DescribeTable("reports a result it cannot decode instead of dropping it",
|
||||
func(opt *searchsvc.AggregationOption, response string) {
|
||||
_, err := aggs.Parse([]*searchsvc.AggregationOption{opt}, json.RawMessage(response))
|
||||
@@ -131,5 +173,8 @@ var _ = Describe("Aggregations", func() {
|
||||
Entry("malformed json", &searchsvc.AggregationOption{Field: "audio.artist"}, `{`),
|
||||
Entry("a terms aggregation", &searchsvc.AggregationOption{Field: "audio.artist"}, `{"a_0": {"buckets": "none"}}`),
|
||||
Entry("a bucket", &searchsvc.AggregationOption{Field: "audio.artist"}, `{"a_0": {"buckets": [{"key": "Saxon", "doc_count": "many"}]}}`),
|
||||
Entry("a metric",
|
||||
&searchsvc.AggregationOption{Field: "audio.year", MetricDefinition: &searchsvc.MetricDefinition{Kind: searchsvc.MetricKind_METRIC_KIND_SUM}},
|
||||
`{"a_0": {"count": "many"}}`),
|
||||
)
|
||||
})
|
||||
@@ -741,9 +741,12 @@ Fixtures:
|
||||
| AGG-03 | `mediatype:audio` reads `artist and album buckets in one request` | audio.albu... Steel=2, audio.albu...Spades=1, audio.album Bomber=2, audio.artist Motörhead=3, audio.artist Saxon=2 | audio.albu... Steel=2, audio.albu...Spades=1, audio.album Bomber=2, audio.artist Motörhead=3, audio.artist Saxon=2 | audio.albu... Steel=2, audio.albu...Spades=1, audio.album Bomber=2, audio.artist Motörhead=3, audio.artist Saxon=2 | ✅ |
|
||||
| AGG-04 | `mediatype:audio` reads `audio.year buckets per decade` | audio.year 1970..1980=2, audio.year 1980..1990=1, audio.year 1990..2000=1, audio.year 2000..2010=3 | audio.year 1970..1980=2, audio.year 1980..1990=1, audio.year 1990..2000=1, audio.year 2000..2010=3 | audio.year 1970..1980=2, audio.year 1980..1990=1, audio.year 1990..2000=1, audio.year 2000..2010=3 | ✅ |
|
||||
| AGG-05 | `mediatype:audio` reads `open-ended audio.year ranges` | audio.year ..1990=3, audio.year 2000..=3 | audio.year ..1990=3, audio.year 2000..=3 | audio.year ..1990=3, audio.year 2000..=3 | ✅ |
|
||||
| AGG-06 | `mediatype:audio` reads `top-level metrics on audio.year` | audio.year max=2009, audio.year min=1971, audio.year sum=13942, audio.year... count=7 | audio.year max=2009, audio.year min=1971, audio.year sum=13942, audio.year... count=7 | audio.year max=2009, audio.year min=1971, audio.year sum=13942, audio.year... count=7 | ✅ |
|
||||
| AGG-07 | `mediatype:image` reads `photo.takenDateTime buckets per date range, an empty range counts zero` | photo.take...00:00Z=0, photo.take...00:00Z=1, photo.take...00:00Z=2, photo.take...00:00Z=2 | photo.take...00:00Z=0, photo.take...00:00Z=1, photo.take...00:00Z=2, photo.take...00:00Z=2 | photo.take...00:00Z=0, photo.take...00:00Z=1, photo.take...00:00Z=2, photo.take...00:00Z=2 | ✅ |
|
||||
| AGG-08 | `mediatype:image` reads `open-ended date ranges` | photo.take...00:00Z=3, photo.take...:00Z..=1 | photo.take...00:00Z=3, photo.take...:00Z..=1 | photo.take...00:00Z=3, photo.take...:00Z..=1 | ✅ |
|
||||
| AGG-09 | `mediatype:image` reads `malformed date range bound` | bad request | bad request | bad request | ✅ |
|
||||
| AGG-18 | `mediatype:audio` reads `two range aggregations and a metric on audio.year stay apart` | audio.year ..1980=2, audio.year ..2000=4, audio.year 1980..=5, audio.year 2000..=3, audio.year max=2009 | audio.year ..1980=2, audio.year ..2000=4, audio.year 1980..=5, audio.year 2000..=3, audio.year max=2009 | audio.year ..1980=2, audio.year ..2000=4, audio.year 1980..=5, audio.year 2000..=3, audio.year max=2009 | ✅ |
|
||||
| AGG-21 | `mediatype:image` reads `a metric without a single value has none` | audio.year avg none, audio.year min none, audio.year sum none | audio.year avg none, audio.year min none, audio.year sum none | audio.year avg none, audio.year min none, audio.year sum none | ✅ |
|
||||
| AGG-34 | `mediatype:audio` reads `term buckets on the numeric audio.year` | audio.year 1971=1, audio.year 1975=1, audio.year 1982=1, audio.year 1999=1, audio.year 2001=1, audio.year 2005=1, audio.year 2009=1 | audio.year 1971=1, audio.year 1975=1, audio.year 1982=1, audio.year 1999=1, audio.year 2001=1, audio.year 2005=1, audio.year 2009=1 | audio.year 1971=1, audio.year 1975=1, audio.year 1982=1, audio.year 1999=1, audio.year 2001=1, audio.year 2005=1, audio.year 2009=1 | ✅ |
|
||||
| AGG-37 | `mediatype:audio` reads `term buckets on the bool audio.hasDrm, spelled true and false` | audio.hasDrm false=1, audio.hasDrm true=1 | audio.hasDrm false=1, audio.hasDrm true=1 | audio.hasDrm false=1, audio.hasDrm true=1 | ✅ |
|
||||
| AGG-39 | `mediatype:audio` reads `no bucket for the empty Title of every match` | no match | no match | no match | ✅ |
|
||||
|
||||
@@ -3,6 +3,7 @@ package parity
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
|
||||
"github.com/opencloud-eu/opencloud/pkg/conversions"
|
||||
searchService "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/search/v0"
|
||||
"github.com/opencloud-eu/opencloud/services/search/pkg/aggregation"
|
||||
"github.com/opencloud-eu/opencloud/services/search/pkg/search"
|
||||
)
|
||||
|
||||
@@ -96,6 +98,10 @@ func aggregationCases() []aggCase {
|
||||
ranges := func(rs ...*searchService.BucketRange) *searchService.BucketDefinition {
|
||||
return &searchService.BucketDefinition{Ranges: rs}
|
||||
}
|
||||
metric := func(field string, kind searchService.MetricKind) *searchService.AggregationOption {
|
||||
return &searchService.AggregationOption{Field: field, MetricDefinition: &searchService.MetricDefinition{Kind: kind}}
|
||||
}
|
||||
|
||||
return []aggCase{
|
||||
{id: 1, query: "mediatype:audio", reads: "term buckets on audio.artist",
|
||||
aggs: []*searchService.AggregationOption{{Field: "audio.artist", Size: 10}},
|
||||
@@ -121,6 +127,14 @@ func aggregationCases() []aggCase {
|
||||
&searchService.BucketRange{From: "2000"},
|
||||
)}},
|
||||
want: []string{"audio.year ..1990=3", "audio.year 2000..=3"}},
|
||||
{id: 6, query: "mediatype:audio", reads: "top-level metrics on audio.year",
|
||||
aggs: []*searchService.AggregationOption{
|
||||
metric("audio.year", searchService.MetricKind_METRIC_KIND_SUM),
|
||||
metric("audio.year", searchService.MetricKind_METRIC_KIND_MIN),
|
||||
metric("audio.year", searchService.MetricKind_METRIC_KIND_MAX),
|
||||
metric("audio.year", searchService.MetricKind_METRIC_KIND_AVG),
|
||||
},
|
||||
want: []string{"audio.year sum=13942", "audio.year min=1971", "audio.year max=2009", "audio.year avg sum=13942 count=7"}},
|
||||
{id: 7, query: "mediatype:image", reads: "photo.takenDateTime buckets per date range, an empty range counts zero",
|
||||
aggs: []*searchService.AggregationOption{{Field: "photo.takenDateTime", BucketDefinition: ranges(
|
||||
&searchService.BucketRange{From: "2018-08-11T00:00:00Z", To: "2018-08-12T00:00:00Z"},
|
||||
@@ -145,6 +159,24 @@ func aggregationCases() []aggCase {
|
||||
&searchService.BucketRange{From: "2018-08-11T00:00:00Z", To: "not-a-date"},
|
||||
)}},
|
||||
wantBadRequest: true},
|
||||
{id: 18, query: "mediatype:audio", reads: "two range aggregations and a metric on audio.year stay apart",
|
||||
aggs: []*searchService.AggregationOption{
|
||||
{Field: "audio.year", BucketDefinition: ranges(&searchService.BucketRange{To: "1980"}, &searchService.BucketRange{From: "1980"})},
|
||||
{Field: "audio.year", BucketDefinition: ranges(&searchService.BucketRange{To: "2000"}, &searchService.BucketRange{From: "2000"})},
|
||||
metric("audio.year", searchService.MetricKind_METRIC_KIND_MAX),
|
||||
},
|
||||
want: []string{
|
||||
"audio.year ..1980=2", "audio.year 1980..=5",
|
||||
"audio.year ..2000=4", "audio.year 2000..=3",
|
||||
"audio.year max=2009",
|
||||
}},
|
||||
{id: 21, query: "mediatype:image", reads: "a metric without a single value has none",
|
||||
aggs: []*searchService.AggregationOption{
|
||||
metric("audio.year", searchService.MetricKind_METRIC_KIND_SUM),
|
||||
metric("audio.year", searchService.MetricKind_METRIC_KIND_MIN),
|
||||
metric("audio.year", searchService.MetricKind_METRIC_KIND_AVG),
|
||||
},
|
||||
want: []string{"audio.year sum none", "audio.year min none", "audio.year avg none"}},
|
||||
{id: 34, query: "mediatype:audio", reads: "term buckets on the numeric audio.year",
|
||||
aggs: []*searchService.AggregationOption{{Field: "audio.year"}},
|
||||
want: []string{
|
||||
@@ -163,7 +195,7 @@ func aggregationCases() []aggCase {
|
||||
}
|
||||
|
||||
// renderAggregations flattens an answer into comparable strings, one per
|
||||
// bucket.
|
||||
// bucket or metric.
|
||||
func renderAggregations(resp *searchService.SearchIndexResponse, err error) []string {
|
||||
if err != nil {
|
||||
if _, ok := err.(errtypes.BadRequest); ok {
|
||||
@@ -181,6 +213,18 @@ func renderAggregations(resp *searchService.SearchIndexResponse, err error) []st
|
||||
}
|
||||
|
||||
func renderAggregation(prefix string, a *searchService.AggregationResult) []string {
|
||||
if m := a.GetMetric(); m != nil {
|
||||
kind := strings.ToLower(strings.TrimPrefix(m.GetKind().String(), "METRIC_KIND_"))
|
||||
value, ok := aggregation.MetricValue(m)
|
||||
switch {
|
||||
case !ok:
|
||||
return []string{prefix + fmt.Sprintf("%s %s none", a.Field, kind)}
|
||||
case m.GetKind() == searchService.MetricKind_METRIC_KIND_AVG:
|
||||
return []string{prefix + fmt.Sprintf("%s avg sum=%v count=%d", a.Field, m.GetSum(), m.GetCount())}
|
||||
}
|
||||
return []string{prefix + fmt.Sprintf("%s %s=%v", a.Field, kind, value)}
|
||||
}
|
||||
|
||||
out := []string{}
|
||||
for _, b := range a.Buckets {
|
||||
out = append(out, prefix+fmt.Sprintf("%s %s=%d", a.Field, b.Key, b.Count))
|
||||
|
||||
Reference in new issue
Block a user