7. Exchangelib3.2官方文档 —— 搜索

搜索功能API是根据Django的queryset API实现的,并且大部分API都是受支持的。就像在Django中一样,QuerySet是惰性的,在QuerySet被迭代之前不会查询任何东西。QuerySet支持链式查询,因此您可以通过多个步骤构建最终查询,并且可以在多个子搜索中重用基本查询集。QuerySet返回一个迭代器,当QuerySet第一次迭代时缓存结果。
具体实例如下:

from datetime import timedelta
from exchangelib import Account, EWSDateTime, FolderCollection, Q, Message

a = Account(...)

# 并不是所有属性都可以搜索,下面代码将打印出所有的可搜索属性
print([f.name for f in Message.FIELDS if f.is_searchable])

all_items = a.inbox.all()  # 获得所有项
all_items_without_caching = a.inbox.all().iterator()  # 获得所有项,但不缓存
# 链接多个过滤以优化查询
filtered_items = a.inbox.filter(subject__contains='foo').exclude(categories__icontains='bar')
status_report = a.inbox.all().delete()  # 删除QuerySet查询的所有项
start = a.default_timezone.localize(EWSDateTime(2017, 1, 1))
end = a.default_timezone.localize(EWSDateTime(2018, 1, 1))
items_for_2017 = a.calendar.filter(start__range=(start, end))  # 过滤指定日期内容

# 和filter()类似,但如果没有指定项将抛出异常
item = a.inbox.get(subject='unique_string')

# 可以使用get()函数来获取指定id或changekey的实例
a.inbox.get(id='AAMkADQy=')
a.inbox.get(id='AAMkADQy=', changekey='FwAAABYA')

# 多个属性排序,'-'表示倒序
# 由于排序在服务器端完成,因此效率很高。但日历视图在多个字段排序则不同。
ordered_items = a.inbox.all().order_by('subject')
reverse_ordered_items = a.inbox.all().order_by('-subject')
 # 已索引的属性可以通过该属性的属性内容进行排序
sorted_by_home_street = a.contacts.all().order_by('physical_addresses__Home__street')
# 注意以下排序操作是在客户端完成的
a.calendar.view(start=start, end=end).order_by('subject', 'categories')

# 计数和判断是否存在
n = a.inbox.all().count()  # 计数
folder_is_empty = not a.inbox.all().exists()  # 判断是否存在

# 限制返回属性
sparse_items = a.inbox.all().only('subject', 'start')
# Dig deeper on indexed properties
sparse_items = a.contacts.all().only('phone_numbers')
sparse_items = a.contacts.all().only('phone_numbers__CarPhone')
sparse_items = a.contacts.all().only('physical_addresses__Home__street')

# 以字典而非对象形式返回
ids_as_dict = a.inbox.all().values('id', 'changekey')
# 以嵌套列表形式返回值
values_as_list = a.inbox.all().values_list('subject', 'body')
# 以列表形式返回值
all_subjects = a.inbox.all().values_list('physical_addresses__Home__street', flat=True)

# QuerySet可以像普通的Python列表一样进行索引和切片操作
# 查询集的切片和索引效率很高,因为它只获取切片后的内容
# 从末尾进行切片也很有效,但最好将排序颠倒过来
first_ten = a.inbox.all().order_by('-subject')[:10]  # 高效,只获取前10个
last_ten = a.inbox.all().order_by('-subject')[:-10]  # 高效但有些繁琐
next_ten = a.inbox.all().order_by('-subject')[10:20]  # 高效,获取10-19项
single_item = a.inbox.all().order_by('-subject')[34298]  # 高效,只获取一项
ten_items = a.inbox.all().order_by('-subject')[3420:3430]  # 高效,只获取3420-3429项
random_emails = a.inbox.all().order_by('-subject')[::3]  # 效率很低,但能运行

# filter()语法和Django的QuerySet.filters类似, filter支持以下查找类型。
# 有些查找仅适用于字符串属性。Range和less/greater运算符仅适用于日期或数值属性。这由字段类型决定。
#
# 在EWS中,有些属性不能进行查找,这由"is_searchable"确定

# 列出特定项目类型的可搜索字段的字段名称和字段类型
for f in Message.FIELDS:
    if f.is_searchable:
        print(f.name, f)

qs = a.calendar.all()  # 返回所有项
qs.filter(subject='foo')  # 返回主题为'foo'的项,区分大小写
qs.filter(start__range=(start, end))  # 返回范围内的所有项
qs.filter(subject__in=('foo', 'bar'))  # 返回主题'foo'或'bar'的所有项
qs.filter(subject__not='foo')  # 返回主不是'foo'的所有项
qs.filter(start__gt=start)  # 返回开始时间大于start的所有项
qs.filter(start__gte=start)  # 返回开始时间大于等于start的所有项
qs.filter(start__lt=start)  # 返回开始时间小于start的所有项
qs.filter(start__lte=start)  # 返回开始时间小于等于start的所有项
qs.filter(subject__exact='foo')  # 和filter(subject='foo')一样
qs.filter(subject__iexact='foo')  #  返回主题'foo','FOO'或者'Foo'的项
qs.filter(subject__contains='foo')  # 返回主题包含'foo'的项
qs.filter(subject__icontains='foo')  # 返回主题包含'foo','FOO'或者'Foo'的项
qs.filter(subject__startswith='foo')  # 返回主题以'foo'开始的项
# 返回主题以'foo','FOO'或者'Foo'开始的项
qs.filter(subject__istartswith='foo')
# 返回至少分配了一个类别的项,即该字段存在于服务器上的项上。
qs.filter(categories__exists=True)
# 返回未设置类别的项,即服务器上的项上不存在该字段。
qs.filter(categories__exists=False)

# 警告:EWS不完全支持对“body”字段的过滤。

# filter()支持EWS的查询字符串,只需要将字符串赋值给filter函数即可
# QueryStrings不能与其他filters链接. 
# 我们不验证QueryString的语法,只将字符串逐字传递给EWS
#
# 从以下页面获取关于QueryString的更多语法信息:
# https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/querystring-querystringtype
a.inbox.filter('subject:XXX')

# filter()还支持Q对象,和Django的Q对象类似,用于构建复杂的布尔逻辑搜索表达式
q = (Q(subject__iexact='foo') | Q(subject__contains='bar')) & ~Q(subject__startswith='baz')
a.inbox.filter(q)

# 在这个例子中,我们按类别过滤,只获取我们创建的项目
a.calendar.filter(
    start__lt=a.default_timezone.localize(EWSDateTime(2019, 1, 1)),
    end__gt=a.default_timezone.localize(EWSDateTime(2019, 1, 31)),
    categories__contains=['foo', 'bar'],
)

# 默认情况下,EWS只返回主循环项目。如果要扩展定期日历项,请calendar.view(start=..., end=...)
items = a.calendar.view(
    start=a.default_timezone.localize(EWSDateTime(2019, 1, 31)),
    end=a.default_timezone.localize(EWSDateTime(2019, 1, 31)) + timedelta(days=1),
)
for item in items:
    print(item.start, item.end, item.subject, item.body, item.location)

# 可以将view()与其他修饰符结合使用。例如,要在添加8:00到10:00的会议之前检查是否存在:
has_conflicts = a.calendar.view(
    start=a.default_timezone.localize(EWSDateTime(2019, 1, 31, 8)),
    end=a.default_timezone.localize(EWSDateTime(2019, 1, 31, 10)),
    max_items=1
).exists()

# 过滤语法也适用于文件夹集合,因此您可以在一个请求中搜索多个文件夹
a.inbox.children.filter(subject='foo')
a.inbox.walk().filter(subject='foo')
a.inbox.glob('foo*').filter(subject='foo')
# Or select the folders individually
FolderCollection(account=a, folders=[a.inbox, a.calendar]).filter(subject='foo')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值