$lookup与大小写敏感字段

3

我知道如何进行不区分大小写的搜索。

例子:

  • members.email: aaa@aaa.com BUT :
  • users.email: AAA@aaa.com

    db.getCollection('members').aggregate([
    {$lookup: {'from': 'users', 'localField': 'members.email', 'foreignField': 'email', 'as': 'users'}},
    {$unwind: {path: '$users', preserveNullAndEmptyArrays: true}},
    {$match : { users: { $exists: false } }},
    ]);
    

集合成员的样子如下:

{
"_id" : ObjectId("5b439c02a5439e00568291fe"),
"members" : [ 
    {
        "email" : "aaa@gmail.com"
    }, 
    {
        "email" : "bbb@gmail.com"
    }, 
    {
        "email" : "ccc@gmail.com"
    }
],
"groupname" : "abuse",
"active" : true,
"createdAt" : ISODate("2018-07-09T17:31:46.098Z"),
"updatedAt" : ISODate("2018-07-09T17:31:46.098Z"),
"__v" : 0
}

集合成员member_user的样式如下:

{
"_id" : ObjectId("5a7dfce545e13f0233b2e451"),
"email" : "AAA@gmail.com",
"__v" : 0
}

{
"_id" : ObjectId("5b43ac89bfd90aa9cc4a68c2"),
"email" : "bbb@gmail.com",
"__v" : 0
}

这是我使用的代码:
    db.getCollection('member').aggregate([
    {$unwind: "$members"},
    {$lookup: {'from': 'member_user', 'localField': 'members.email', 'foreignField': 'email', 'as': 'users'}},
    {$unwind: {path: '$users', preserveNullAndEmptyArrays: true}},
    {$match : { users: { $exists: false } }},
], 
{
    collation: {
        locale: 'en_US',
        strength: 1
    }
}
    );

当数据集较小时,速度通常很快。但是我有24K个成员和7K个用户。正如我所说,当{$match : { users: { $exists: true } }}时,速度还可以,但当{$match : { users: { $exists: false } }}时,速度几乎慢了60倍(1秒 vs 1分钟)。

没有排序规则(collation),速度总是很快的。


你在这里有什么问题? - Ashh
在 $lookup 中,aaa@aaa.comAAA@aaa.com 不相同。因此,在 $unwind 之后,“users”将不存在。结果将包含“aaa@aaa.com”。但是我想得到“空”结果。 - Kaman Wu
你的 localFieldforeignField 是否区分大小写匹配? - Ashh
我希望我的localField和foreignField进行大小写不敏感的匹配。但是现在看起来它们是大小写敏感的匹配。如何使它们进行大小写不敏感的匹配? - Kaman Wu
请检查答案。 - Ashh
显示剩余2条评论
1个回答

3

您需要使用$toLower聚合将localFieldforeignField转换为小写,然后您可以轻松匹配您的字段。

db.collection.aggregate([
  { "$unwind": "$members" },
  { "$addFields": { "members.email": { "$toLower": "$members.email" }}},
  { "$lookup": {
    "from": "users",
    "let": { "membersEmail": "$members.email" },
    "pipeline": [
      { "$addFields": { "email": { "$toLower": "$email" }}},
      { "$match": { "$expr": { "$eq": [ "$email", "$$membersEmail" ] } } }
    ],
    "as": "members.email"
  }},
  { "$unwind": "$members.email" },
  {  "$group": {
    "_id": "$_id",
    "groupname": { "$first": "$groupname" },
    "active": { "$first": "$active" },
    "members": { "$push": "$members.email" }
  }}
])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接