【问题标题】:NET::LDAP FIlter with ORNET::LDAP 过滤器与 OR
【发布时间】:2016-06-14 12:13:26
【问题描述】:

在 PERL, NET::LDAP 中,我正在尝试使用-

my $psearch-$ldap->search(   
    base => $my_base,
    attr => ["mail","employeeNumber","physicalDeliveryOfficeName"],
    filter => "(&(mail=*)(!(employeeNumber=9*)) (&(physicalDeliveryOfficeName=100)) (|(physicalDeliveryOfficeName=274)))");

说“给我每个人都有一个邮件条目,其中员工编号不是以 9 开​​头,physicalDeliveryOfficeName 是 100 或 274”。

我可以仅使用 100 或仅使用 274 使其工作,但我似乎无法弄清楚如何指定 100 OR 274。

我似乎找不到正确的过滤器字符串,准备把我的头发拉出来...请帮助!!

【问题讨论】:

  • 不会是:(&(mail=*)(!(employeeNumber=9*)) (&(physicalDeliveryOfficeName=100)(|(physicalDeliveryOfficeName=274)))) 吗?跨度>
  • 我试过了,我得到 0 个结果。似乎它应该是正确的,这就是为什么我这么难过!

标签: perl filter ldap


【解决方案1】:

我无法对此进行测试,但 LDAP 查询使用 prefix 表示法,而我们习惯使用 infix 表示法。想象一下,如果你想要一个 dog 或 cat 的东西。在 infix 表示法中,它看起来像这样:

((ANIMAL = "cat") OR (ANIMAL = "dog"))

使用 prefix 表示法,布尔运算符位于查询的 开始:

(OR (ANIMAL = "cat") (ANIMAL = "dog"))

前缀表示法的优势在于您对每个布尔值进行两次以上的检查。在这里,我正在寻找猫、狗或袋熊的东西:

(OR (ANIMAL = "cat") (ANIMAL = "dog") (ANIMAL = "wombat"))

请注意,我的语句前面只需要一个布尔运算符。这会将所有三个语句 OR 组合在一起。使用我们的标准 infix 表示法,我必须有第二个 OR 运算符:

((ANIMAL = "cat") OR (ANIMAL = "dog") OR (ANIMAL = "wombat"))

前缀符号是由波兰数学家 Jan Lukasiewicz 于 1924 年在华沙大学创建的,因此被称为 Polish Notation。后来发现,如果等式用与波兰表示法相反的后缀表示法编写,计算机可以从前到后处理一个等式。因此,Reverse波兰表示法(或RPN)诞生了。

早期的 HP 计算器使用 RPN 表示法,这在 1970 年代初成为 Geek Sheik 的东西。想象一下,当您将计算器交给某人而他们不知道如何使用它时,您会获得一种大脑优越感。当时唯一让自己更酷的方法就是拥有Curta。

好吧,走怀旧小路就够了。让我们回到问题上来……

构造中缀操作的最简单方法是构建你想要的树形图。因此,您应该将 LDAP 查询草拟为一棵树:

                             AND
                            / | \
                           /  |  \
                          /   |   \
                         /    |    \
                        /     |     \
                       /      |      \
                      /       |       \
                    OR  employee!=9*  mail=*
                   /  \
                  /    \
                 /      \
                /        \
               /          \
phyDelOfficeName=100   phyDelOfficeName=274

要基于此树构建查询,请从树的底部开始,然后逐层向上。我们树的底部是查询的 OR 部分:

(OR (physicalDeliveryOfficeName = 100) (physicalDeliveryOfficeName = 274))

使用 LDAP 的 OR 运算符,管道 (|) 并删除多余的空格,我们得到:

(|(physicalDeliveryOfficeName = 100)(physicalDeliveryOfficeName = 274))

当我构建一个 LDAP 查询时,我喜欢将每个部分保存为一个 Perl 标量变量。它使它更易于使用:

$or_part = "|(physicalDeliveryOfficeName=100)(physicalDeliveryOfficeName=274)";

请注意,我已经省略了外部对或括号。当您将所有查询串在一起时,括号外的一组返回。然而,有些人还是把它们放在了一起。额外的一组括号不会影响 LDAP 查询。

现在是查询的其他两部分:

$mailAddrExists = "mail=*";
$not_emp_starts_9 = "!(employee=9*)";

现在我们AND将所有三个部分放在一起:

"(&($mailAddrExists)($not_emp_starts_9)($or_part))"

请注意,单个 & 符号将所有内容编织在一起。我可以替换每个部分以查看完整的查询:

(&(mail=*)(!(employee=9*))(|(physicalDeliveryOfficeName=100)(physicalDeliveryOfficeName=274)))

或者像这样:

my $psearch-$ldap->search(   
    base => $my_base,
    attr => ["mail","employeeNumber","physicalDeliveryOfficeName"],
    filter => "(&(mail=*)(!(employee=9*))(|(physicalDeliveryOfficeName=100)(physicalDeliveryOfficeName=274)))",
);

或零碎:

my $mail = "mail=*";
my $employee = "!(employee=9*)";
my $physicalAddress = "|(physicalDeliveryOfficeName=100)"
     . "(physicalDeliveryOfficeName=274)";

my $psearch-$ldap->search(   
    base => $my_base,
    attr => ["mail","employeeNumber","physicalDeliveryOfficeName"],
    filter => "(&($mail)($employee)($physicalAddress))",
);

正如我之前所说,我无法对此进行测试。我希望它有效。如果不出意外,我希望您了解如何创建 LDAP 查询并自己弄清楚如何去做。

【讨论】:

  • 为什么,这太棒了!非常感谢您的解释!这肯定会在我的同事之间分享。我对那个符号有一个想法,但无法理解它。树是该方法的完美视觉表示。顺便说一句 - 它有效!
  • @user973828:如果可行,请接受答案。当你在它的时候投一个+1不会有什么坏处。这是我在 SO 上看到的最好的答案之一,我不明白为什么这还没有收到一个赞成票,而更受欢迎的用户的琐碎答案在几分钟内就获得了 10 多个赞成票。
猜你喜欢
  • 1970-01-01
  • 2011-01-17
  • 2014-05-31
  • 2020-11-08
  • 2014-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多