基于层次匹配的规则引擎

时间:2020-02-23 10:53:24

标签: python algorithm matching rule-engine

说,我有一个具有以下结构的数据集(城市):

  • ID
  • 城市
  • 状态
  • 国家
  • 大陆

我有一个配置表(键,值),其中键可以是上述参数的组合

例如:

{
    "continent": "asia"
}

{
    "continent": "asia",
    "country" : "india"
}

{
    "continent": "asia",
    "country" : "india",
    "state" : "maharashtra",
    "city" : "mumbai"
}

现在,我想从第一个数据集到配置中的条目最接近城市。

例如,如果我有

city: mumbai, state: maharashtra, country: india, continent: asia

它应该与上面配置中的第3个条目匹配。

如果我有

city: tokyo, state: Kantō, country: japan, continent: asia

它应该与上面配置中的第一个条目匹配。

我正在寻找建议,以解决这种情况。

我愿意以任何其他方式存储配置。

理想情况下,我想要一个可以传递多个条目(输入)的解决方案,它应该为每个输入返回最匹配的配置。

1 个答案:

答案 0 :(得分:1)

冒着我误解这个问题的风险,我会:

  • 以树状数据结构收集配置条目,以加快检索速度
  • 遍历那棵树一次找到一个数据条目的匹配项

这是它的外观:

class Config:
    def __init__(self):
        self.continents = {}

    def add(self, config):
        collection = self.continents
        for prop in ["continent", "country", "state", "city"]:
            if prop not in config:
                break
            key = config[prop]
            if key not in collection:
                collection[key] = {}
            collection = collection[key]
        collection["config"] = config

    def get(self, data):
        collection = self.continents
        config = None
        for prop in ["continent", "country", "state", "city"]:
            if prop not in data or data[prop] not in collection:
                break
            collection = collection[data[prop]]
            if "config" in collection:
                config = collection["config"]
        return config

以上类可以如下使用。

首先创建一个实例,并使用配置条目填充它:

config = Config()

config.add({ "continent": "asia"})
config.add({ "continent": "asia", "country": "india" })
config.add({ "continent": "asia", "country": "india", 
             "state": "maharashtra", "city": "mumbai" })

然后迭代您的数据条目,并针对每次调用config.get获得最佳匹配配置。例如:

print(config.get({ "city": "mumbai", "state": "maharashtra", 
                   "country": "india", "continent": "asia"}))

print(config.get({"city": "tokyo", "state": "kantō", 
                   "country": "japan", "continent": "asia"}))