From 53bb96004bb07aafd195c8b94ec4a1d1e39bdf96 Mon Sep 17 00:00:00 2001 From: Andrey Vertiprahov Date: Thu, 9 Sep 2021 21:32:02 +0500 Subject: [PATCH 1/2] Optimize mongo query in Label.get_instance_profile method. --- inv/models/interfaceprofile.py | 1 + main/models/label.py | 47 +++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/inv/models/interfaceprofile.py b/inv/models/interfaceprofile.py index ad1898701b..b1b9d58eaa 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 849b7599d4..eb99a7d6e8 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,14 @@ class Label(Document): } for r in cursor.fetchall() ] + sef = set(effective_labels) for profile in match_profiles: + print(profile) 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 -- GitLab From 30ad399e50a5dfeac89c5046004c434df7c7da8c Mon Sep 17 00:00:00 2001 From: Andrey Vertiprahov Date: Thu, 9 Sep 2021 21:51:29 +0500 Subject: [PATCH 2/2] Fix print. --- main/models/label.py | 1 - 1 file changed, 1 deletion(-) diff --git a/main/models/label.py b/main/models/label.py index eb99a7d6e8..89fdf3ec5e 100644 --- a/main/models/label.py +++ b/main/models/label.py @@ -751,7 +751,6 @@ class Label(Document): ] sef = set(effective_labels) for profile in match_profiles: - print(profile) if "handler" in profile and profile["handler"]: handler = Handler.get_by_id(profile["handler"]) if handler(effective_labels): -- GitLab