How can I optimise the following LDAP filter to remove the duplication in the code?
(|(&(cn=PATH*)(cn=*2013*)(|(cn=*_S1_*)(cn=*_1_*)))(&(cn=MICR*)(cn=*2013*)(|(cn=*_S1_*)(cn=*_1_*))))
通常,您可以做的最重要的优化操作是确保LDAP 服务器上的索引正确。不过,这无助于简化实际的过滤器……这个问题(几乎)是简单的布尔表达式简化。
首先,将LDAP 过滤器前缀表示法转换为中缀表示法(一些示例算法)。我正在为过滤器项目使用占位符符号:
a cn=PATH*
b cn=*2013*
c cn=*_S1_*
d cn=*_1_*
e cn=MICR*
所以这个前缀符号过滤器
(|(&(a)(b)(|(c)(d)))(&(e)(b)(|(c)(d))))
成为这个中缀符号过滤器:
(a&b&(c|d))|(e&b&(c|d))
然后使用任何普通的布尔表达式优化器/简化器,我很懒所以让Wolfram 来做。
现在找出最简单的最小形式结果,DNF或CNF形式只有and
和or
操作,这些可以很容易地用作 LDAP 过滤器(任何没有 ⊻ "xor" 的东西都可能很好)。CNF在这里显然更简单:
DNF (a ∧ b ∧ c) ∨ (a ∧ b ∧ d) ∨ (b ∧ c ∧ e) ∨ (b ∧ d ∧ e)
CNF (a ∨ e) ∧ b ∧ (c ∨ d)
(“∧”是“和”,“∨”是“或”)
将其转回前缀过滤器并替换您获得的符号:
(& (| (cn=PATH*)(cn=MICR*) )
(cn=*2013*)
(| (cn=*_S1_*)(cn=*_1_*) )
)
最后一个微不足道的优化,您可以合并某些类型的子字符串匹配,而无需在它们不重叠时使用运算符:
(& (| (cn=PATH*2013*)(cn=MICR*2013*))
(| (cn=*_S1_*)(cn=*_1_*))
)
如果您需要以编程方式为任意过滤器执行此操作,您可以轻松找到执行前缀/中缀转换的代码,以及 PHP 中的布尔表达式优化,这些是解析器和表达式评估中的常见问题。
我怀疑当您有零个或一个时,您需要将术语与前缀/中缀/后缀字符串进行特殊情况合并,我不知道这样一个过程的名称。在任何情况下,您都需要它来了解 LDAPattribute=
语法。