diff --git a/inv/models/interfaceprofile.py b/inv/models/interfaceprofile.py index ad1898701b0deabb5580a524aa934714b0d6d90f..b1b9d58eaa53baf586680b0be9e0ce15f22e9c9e 100644 --- a/inv/models/interfaceprofile.py +++ b/inv/models/interfaceprofile.py @@ -88,6 +88,7 @@ class InterfaceProfile(Document): "auto_create_index": False, "indexes": [ "match_rules.labels", + ("match_rules.dynamic_order", "match_rules.labels"), ("dynamic_classification_policy", "match_rules.labels"), ], } diff --git a/main/models/label.py b/main/models/label.py index 849b7599d4adbdf3d5664098c9c80de6d744afa3..89fdf3ec5e26002e93fb7a6e36b4ca74c08cce52 100644 --- a/main/models/label.py +++ b/main/models/label.py @@ -703,28 +703,33 @@ class Label(Document): :param kwargs: :return: """ - effective_labels = instance.effective_labels or [] + effective_labels = Label.merge_labels(instance.iter_effective_labels(instance)) if is_document(instance): coll = profile_model._get_collection() - match_profiles = coll.aggregate( - [ - {"$unwind": "$match_rules"}, - { - "$match": { - "match_rules.dynamic_order": {"$gt": 0}, - "match_rules.labels": {"$in": effective_labels}, - } - }, - { - "$project": { - "dynamic_order": "$match_rules.dynamic_order", - "labels": "$match_rules.labels", - "handlers": 1, + pipeline = [ + { + "$match": { + "match_rules": { + "$elemMatch": { + "dynamic_order": {"$ne": 0}, + "labels": {"$in": effective_labels}, + } } - }, - {"$sort": {"dynamic_order": 1}}, - ] - ) + } + }, + {"$unwind": "$match_rules"}, + { + "$project": { + "dynamic_order": "$match_rules.dynamic_order", + "labels": "$match_rules.labels", + "diff": {"$setDifference": ["$match_rules.labels", effective_labels]}, + "handlers": 1, + } + }, + {"$match": {"diff": []}}, + {"$sort": {"dynamic_order": 1}}, + ] + match_profiles = coll.aggregate(pipeline) else: with connection.cursor() as cursor: query = f""" @@ -744,12 +749,13 @@ class Label(Document): } for r in cursor.fetchall() ] + sef = set(effective_labels) for profile in match_profiles: if "handler" in profile and profile["handler"]: handler = Handler.get_by_id(profile["handler"]) if handler(effective_labels): return profile["_id"] - if not set(profile["labels"]) - set(effective_labels): + if not set(profile["labels"]) - sef: return profile["_id"] @classmethod