Mongoengine / MongoDB 基于字典字段中的键存在的模型过滤
Mongoengine / MongoDB model filtering on basis of key presence in Dictionary field
我正在构建一个 data-model 使用 Mongoengine 来存储一些元数据,在本例中是电子邮件文件。非常精简的模型,只有与我的问题相关的字段,是:
class Email(Document):
headers = DictField()
headers 字典将包含从在 key-value 关系中工作的电子邮件中提取的 header-data。
在这个 header-data 我知道,有时会有一个 header 与名称(和字典键)一起出现: x-mailer
(所有 header 键是自动 lower-cased)。我构建了一个简单的查询来查看 header 是否包含这样的键:
xmailer_emails = Email.objects.filter(headers__exists='x-mailer')
但是,此结果不包含 所有 email
collection 中的条目,但它包含相当多的不将 x-mailer
作为 headers
字典中的键。这是我用来检查结果数据的一些代码:
xmailer_emails = Email.objects.filter(headers__exists='x-mailer'))
log(xmailer_emails._query)
log('Total email count: ' + str(Email.objects.count()))
log('X-Mailer email acount: ' + str(xmailer_emails.count()))
no_xmailer = len([e for e in xmailer_emails if 'x-mailer' not in e.headers])
log('Filtered no x-mailer count: ' + str(no_xmailer))
has_xmailer = len([e for e in xmailer_emails if 'x-mailer' in e.headers])
log('Filtered has x-mailer count: ' + str(has_xmailer))
这是我得到的输出:
[21:32:54 05/27/19] {'headers': {'$exists': 'x-mailer'}}
[21:32:54 05/27/19] Total email count: 86
[21:32:54 05/27/19] X-Mailer email count: 79
[21:32:54 05/27/19] Filtered no x-mailer count: 55
[21:32:54 05/27/19] Filtered has x-mailer count: 24
因此,虽然 collection 中有 86 个条目,但它会在 headers
中的 x-mailer
过滤器上撤回其中的 79 个条目。过滤掉那些只有 24 个实际上在字典中有 key-value。我好像做错了什么,但我不知道是什么。
这里是一些不包含 x-mailer
键的项目的简短转储,这些是键:
dict_keys(['x-receiver', 'to', 'mime-version', 'received', 'x-priority', 'x-sender', 'date', 'content-type', 'message-id', 'subject', 'x-riferimento-message-id', 'from'])
dict_keys(['content-type', 'mime-version'])
dict_keys(['x-wum-to', 'date', 'x-uidl', 'message-id', 'in-reply-to', 'x-wum-replyto', 'x-message-delivery', 'mime-version', 'received', 'x-savecopy', 'authentication-results', 'x-wum-nature', 'x-account-key', 'x-wum-from', 'message-context', 'x-originalarrivaltime', 'x-me-spamrating', 'x-me-spamlevel', 'to', 'x-dkim-result', 'x-mozilla-status', 'x-mozilla-status2', 'references', 'x-auth-result', 'x-store-info', 'return-path', 'x-message-info', 'x-sid-pra', 'x-message-status', 'sender', 'x-wum-cci', 'content-type', 'reply-to', 'subject', 'from'])
dict_keys(['x-ms-has-attach', 'to', 'mime-version', 'received', 'thread-topic', 'x-auto-response-suppress', 'x-ms-exchange-organization-authsource', 'content-language', 'content-type', 'date', 'subject', 'message-id', 'thread-index', 'reply-to', 'from'])
我不知道发生了什么,虽然 exists
运算符有效,但它还包括 non-matching 个文档,但不是 collection.[=26= 中的每个文档]
我还在 mongoengine 存储库上提出了这个问题,但没有回复(除了 exists
运算符的链接 SO 问题):https://github.com/MongoEngine/mongoengine/issues/2059
您实际需要执行的 pymongo 查询如下:
c.find({'headers.x-mailer': {'$exists': True}})
如果你有简单的键(例如 "xmailer" 而不是 "x-mailer"),你可以在 mongoengine 中使用:
Email.objects.filter(headers__xmailer__exists=True))
但您可以使用 raw 运算符实现它:
Email.objects.filter(__raw__={'headers.x-mailer': {'$exists': True}})
我正在构建一个 data-model 使用 Mongoengine 来存储一些元数据,在本例中是电子邮件文件。非常精简的模型,只有与我的问题相关的字段,是:
class Email(Document):
headers = DictField()
headers 字典将包含从在 key-value 关系中工作的电子邮件中提取的 header-data。
在这个 header-data 我知道,有时会有一个 header 与名称(和字典键)一起出现: x-mailer
(所有 header 键是自动 lower-cased)。我构建了一个简单的查询来查看 header 是否包含这样的键:
xmailer_emails = Email.objects.filter(headers__exists='x-mailer')
但是,此结果不包含 所有 email
collection 中的条目,但它包含相当多的不将 x-mailer
作为 headers
字典中的键。这是我用来检查结果数据的一些代码:
xmailer_emails = Email.objects.filter(headers__exists='x-mailer'))
log(xmailer_emails._query)
log('Total email count: ' + str(Email.objects.count()))
log('X-Mailer email acount: ' + str(xmailer_emails.count()))
no_xmailer = len([e for e in xmailer_emails if 'x-mailer' not in e.headers])
log('Filtered no x-mailer count: ' + str(no_xmailer))
has_xmailer = len([e for e in xmailer_emails if 'x-mailer' in e.headers])
log('Filtered has x-mailer count: ' + str(has_xmailer))
这是我得到的输出:
[21:32:54 05/27/19] {'headers': {'$exists': 'x-mailer'}}
[21:32:54 05/27/19] Total email count: 86
[21:32:54 05/27/19] X-Mailer email count: 79
[21:32:54 05/27/19] Filtered no x-mailer count: 55
[21:32:54 05/27/19] Filtered has x-mailer count: 24
因此,虽然 collection 中有 86 个条目,但它会在 headers
中的 x-mailer
过滤器上撤回其中的 79 个条目。过滤掉那些只有 24 个实际上在字典中有 key-value。我好像做错了什么,但我不知道是什么。
这里是一些不包含 x-mailer
键的项目的简短转储,这些是键:
dict_keys(['x-receiver', 'to', 'mime-version', 'received', 'x-priority', 'x-sender', 'date', 'content-type', 'message-id', 'subject', 'x-riferimento-message-id', 'from'])
dict_keys(['content-type', 'mime-version'])
dict_keys(['x-wum-to', 'date', 'x-uidl', 'message-id', 'in-reply-to', 'x-wum-replyto', 'x-message-delivery', 'mime-version', 'received', 'x-savecopy', 'authentication-results', 'x-wum-nature', 'x-account-key', 'x-wum-from', 'message-context', 'x-originalarrivaltime', 'x-me-spamrating', 'x-me-spamlevel', 'to', 'x-dkim-result', 'x-mozilla-status', 'x-mozilla-status2', 'references', 'x-auth-result', 'x-store-info', 'return-path', 'x-message-info', 'x-sid-pra', 'x-message-status', 'sender', 'x-wum-cci', 'content-type', 'reply-to', 'subject', 'from'])
dict_keys(['x-ms-has-attach', 'to', 'mime-version', 'received', 'thread-topic', 'x-auto-response-suppress', 'x-ms-exchange-organization-authsource', 'content-language', 'content-type', 'date', 'subject', 'message-id', 'thread-index', 'reply-to', 'from'])
我不知道发生了什么,虽然 exists
运算符有效,但它还包括 non-matching 个文档,但不是 collection.[=26= 中的每个文档]
我还在 mongoengine 存储库上提出了这个问题,但没有回复(除了 exists
运算符的链接 SO 问题):https://github.com/MongoEngine/mongoengine/issues/2059
您实际需要执行的 pymongo 查询如下:
c.find({'headers.x-mailer': {'$exists': True}})
如果你有简单的键(例如 "xmailer" 而不是 "x-mailer"),你可以在 mongoengine 中使用:
Email.objects.filter(headers__xmailer__exists=True))
但您可以使用 raw 运算符实现它:
Email.objects.filter(__raw__={'headers.x-mailer': {'$exists': True}})