你如何使用 MongoDB $lookup 来 return 一个子字符串,然后使用该子字符串检查另一个集合中的内容

How do you use MongoDB $lookup to return a substring, then check things in another collection with that substring

我正在尝试使用 MongoDB 聚合管道从一个集合中提取项目,检查一个字符串(url),从中提取一个子字符串,然后在第二个集合中检查与第二个集合文档字段之一的所述子字符串匹配的文档。

collection1 文档:

{
    _id: ObjectId('xxxxxxxxxxxxxxxxxxx'),
    url: 'https://example.com/WNE8UH'
}

编辑:productId 并不总是位于 url 字符串的末尾。有时它就在中间,这迫使我在任何比较步骤之前提取它。

collection2 文档:

{
    _id: ObjectId('xxxxxxxxxxxxxxxxxxx'),
    productId: 'WNE8UH'
}

看到 collection1 中的 url 包含 WNE8UH 而 collection2 中的 productId

如何使用聚合return url 的子字符串,然后使用$lookup 定位collection2 productId 字段中的文档?

这是我当前的代码:

db.collection1.aggregation([
    { $match: { url: RegExp( 'example.com', 'i' ) } },
    { $lookup: {
        from: 'collection2',
        
        let: {
            productId: { 
                $regexFind: { 
                    input: "$url", 
                    regex: '(?<=com\/)\w{6}'
             }
           }
        },
        pipeline: [
        {
            $match: { productId: '$$productId'
                }
        }
        ],
        as: 'matching_doc'
        
    }}
])

结果

{
    _id: ObjectId('xxxxxxxxxxxxxxxxxxx'),
    url: 'https://example.com/WNE8UH',
    matching_doc: []
}

获取空数组。我需要获取匹配的文档。

我做错了什么?

查询

  • 查找如果url在URL
  • 的末尾包含productId

*如果此正则表达式不适合您的情况,您可以使用任何其他正则表达式
*如果你想使用索引来匹配 url 你应该创建索引并使用正则表达式 ^ 就像 ^https://example.com/ (我的意思是在你的查询中查找之前)

Playmongo

coll1.aggregate(
[{"$lookup": 
   {"from": "coll2",
    "let": {"url": "$url"},
    "pipeline": 
     [{"$match": 
         {"$expr": 
           {"$regexMatch": 
             {"input": "$$url",
              "regex": {"$concat": ["$productId", {"$literal": "$"}]}}}}}],
    "as": "matching_doc"}}])

编辑

如果 productId 不是最后但总是在域名后面 example.com 你可以使用类似

Playmongo

coll1.aggregate(
[{"$lookup":
   {"from":"coll2",
    "pipeline":
     [{"$match":
         {"$expr":
           {"$regexMatch":
             {"input":"$$url",
              "regex":
               {"$concat":["^https://example.com/", "$productId", "*"]}}}}}],
    "as":"matching_doc",
    "let":{"url":"$url"}}}])

如果它可以在 URL 中的任何地方,你可以使用像波纹管这样的东西

coll1.aggregate(
[{"$lookup": 
   {"from": "coll2",
    "pipeline": 
     [{"$match": 
         {"$expr": 
           {"$regexMatch": {"input": "$$url", "regex": "$productId"}}}}],
    "as": "matching_doc",
    "let": {"url": "$url"}}}])