diff --git a/engine/storage_cdrs_it_test.go b/engine/storage_cdrs_it_test.go index 87f1403e5..72e05abd4 100644 --- a/engine/storage_cdrs_it_test.go +++ b/engine/storage_cdrs_it_test.go @@ -467,7 +467,7 @@ func testGetCDRs(cfg *config.CGRConfig) error { Usage: time.Duration(1) * time.Second, Supplier: "SUPPLIER3", DisconnectCause: "SENT_OK", - ExtraFields: map[string]string{"Hdr4": "HdrVal4"}, + ExtraFields: map[string]string{"Service-Context-Id": "voice@huawei.com"}, CostSource: "", Cost: -1, }, @@ -491,7 +491,7 @@ func testGetCDRs(cfg *config.CGRConfig) error { Usage: time.Duration(1) * time.Second, Supplier: "SUPPLIER3", DisconnectCause: "SENT_OK", - ExtraFields: map[string]string{"Service-Context-Id": "voice@huawei.com"}, + ExtraFields: map[string]string{"Service-Context-Id": "voice2@huawei.com"}, CostSource: "rater", Cost: 0.15, }, @@ -810,9 +810,15 @@ func testGetCDRs(cfg *config.CGRConfig) error { } // Filter *exists on ExtraFields if CDRs, _, err := cdrStorage.GetCDRs(&utils.CDRsFilter{ExtraFields: map[string]string{"Service-Context-Id": "*exists"}}, false); err != nil { - return fmt.Errorf("testGetCDRs #89, err: %v", err) - } else if len(CDRs) != 1 { - return fmt.Errorf("testGetCDRs #90, unexpected number of CDRs returned: %+v", CDRs) + return fmt.Errorf("testGetCDRs #91, err: %v", err) + } else if len(CDRs) != 2 { + return fmt.Errorf("testGetCDRs #92, unexpected number of CDRs returned: %+v", CDRs) + } + // Filter *exists on not ExtraFields + if CDRs, _, err := cdrStorage.GetCDRs(&utils.CDRsFilter{NotExtraFields: map[string]string{"Service-Context-Id": "*exists"}}, false); err != nil { + return fmt.Errorf("testGetCDRs #93, err: %v", err) + } else if len(CDRs) != 7 { + return fmt.Errorf("testGetCDRs #94, unexpected number of CDRs returned: %+v", len(CDRs)) } return nil diff --git a/engine/storage_mongo_stordb.go b/engine/storage_mongo_stordb.go index 8f23f39ed..876b939fd 100644 --- a/engine/storage_mongo_stordb.go +++ b/engine/storage_mongo_stordb.go @@ -1023,15 +1023,20 @@ func (ms *MongoStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([]*CDR, extrafields = append(extrafields, bson.M{"extrafields." + field: value}) } } - filters["$or"] = extrafields + filters["$and"] = extrafields } if len(qryFltr.NotExtraFields) != 0 { var extrafields []bson.M - for field, value := range qryFltr.ExtraFields { - extrafields = append(extrafields, bson.M{"extrafields." + field: value}) + for field, value := range qryFltr.NotExtraFields { + if value == utils.MetaExists { + extrafields = append(extrafields, bson.M{"extrafields." + field: bson.M{"$exists": false}}) + } else { + extrafields = append(extrafields, bson.M{"extrafields." + field: bson.M{"$ne": value}}) + } + } - filters["$not"] = bson.M{"$or": extrafields} + filters["$and"] = extrafields } if qryFltr.MinCost != nil { diff --git a/engine/storage_postgres.go b/engine/storage_postgres.go index b73703c36..261ea75cf 100644 --- a/engine/storage_postgres.go +++ b/engine/storage_postgres.go @@ -195,7 +195,7 @@ func (self *PostgresStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([] qIds.WriteString(" OR") } if value == utils.MetaExists { - qIds.WriteString(fmt.Sprintf(" (extra_fields ->> '%s') IS NOT NULL", field)) + qIds.WriteString(fmt.Sprintf(" extra_fields ?'%s'", field)) } else { qIds.WriteString(fmt.Sprintf(" (extra_fields ->> '%s') = '%s'", field, value)) } @@ -209,9 +209,13 @@ func (self *PostgresStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([] needAnd := false for field, value := range qryFltr.NotExtraFields { if needAnd { - qIds.WriteString(" OR") + qIds.WriteString(" AND") + } + if value == utils.MetaExists { + qIds.WriteString(fmt.Sprintf(" NOT extra_fields ?'%s'", field)) + } else { + qIds.WriteString(fmt.Sprintf(" NOT (extra_fields ?'%s' AND (extra_fields ->> '%s') = '%s')", field, field, value)) } - qIds.WriteString(fmt.Sprintf(" extra_fields -> '%s' = '%s'", field, value)) needAnd = true } qIds.WriteString(" )") diff --git a/engine/storage_sql.go b/engine/storage_sql.go index cc212eb5b..4c5a9caea 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -892,9 +892,13 @@ func (self *SQLStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([]*CDR, needAnd := false for field, value := range qryFltr.NotExtraFields { if needAnd { - qIds.WriteString(" OR") + qIds.WriteString(" AND") + } + if value == utils.MetaExists { + qIds.WriteString(fmt.Sprintf(" extra_fields NOT LIKE '%%\"%s\":%%'", field)) + } else { + qIds.WriteString(fmt.Sprintf(" extra_fields NOT LIKE '%%\"%s\":\"%s\"%%'", field, value)) } - qIds.WriteString(fmt.Sprintf(` extra_fields LIKE '%%"%s":"%s"%%'`, field, value)) needAnd = true } qIds.WriteString(" )")