mongoDB $lookup 与 $search 管道

问题描述 投票:0回答:1

我有两个收藏: store_group集合:

{"_id": ObjectId("674fe7cc4e65df54a0db23b5"),
 "stores": [
  {"id": 101, "name":"abc"},  // 101 as int
  {"id": 204}, "name":"cd"} // 204 as int
]}

location_view_for_search,从商店集合创建的视图:

{"_id": ObjectId("67400d3997214dc99c6311c5"),
  "location_number": "101", // 101 as String
}
{"_id": ObjectId("67400d3997214dc99c6311c6"),
  "location_number": "204", // 204 as String
}

我需要通过 location_number 从 store_group 查找商店数据,并对 location_number 应用自动完成操作。因为store_group集合中的stores._id是数字,而location_view_for_search.location_number是字符串,所以我首先将数字映射到字符串,然后进行查找:

[
  {
    $addFields:
      {
        storeIds: {
          $map: {
            input: "$stores",
            in: {
              $toString: "$$this.id"
            }
          }
        }
      }
  },
  {
    $lookup:
      {
        from: "store_view_for_search",
        localField: "storeIds",
        foreignField: "location_number",
        as: "store_details"
      }
  }
]

到目前为止一切正常,我可以看到管道输出正确显示

store_details

{
  "stores": [
    {"id": 101, "name": "abc"},
    {"id": 204, "name": "cd"}
  ],
  "storeIds":["101", "204"],
  "store_details": [
    {"_id": ObjectId("67400d3997214dc99c6311c5"), "location_number": "101"},
    {"_id": ObjectId("67400d3997214dc99c6311c6"), "location_number": "204"}
  ]
}

接下来我在 $lookup 中添加了 $search 以在 location_view_for_search 中对 location_number 应用自动完成搜索,我创建了图集搜索索引以将 location_number 上的静态映射设置为自动完成。

{
    $lookup:
      {
        from: "location_view_for_search",
        localField: "storeIds",
        foreignField: "location_number",
        as: "store_details",
        pipeline: [
          {
            $search: {
              index:
                "autocomplete-by-location-number",
              compound: {
                should: [
                  {
                    autocomplete: {
                      query: "572",
                      path: "location_number",
                      fuzzy: {
                        maxEdits: 1,
                        prefixLength: 3,
                        maxExpansions: 1
                      }
                    }
                  }
                ],
                minimumShouldMatch: 1
              }
            }
          }
        ]
      }
  }

然后管道输出突然将结果中的

store_details
显示为空数组。我做错了什么? 我在这里关注 mongo 教程https://www.mongodb.com/docs/atlas/atlas-search/tutorial/lookup-with-search/

我还在location_view_for_search视图上测试了相同的$search,它工作正常,我可以通过location_number上的自动完成搜索来搜索位置

mongodb mongodb-query mongodb-atlas mongodb-atlas-search
1个回答
0
投票

这是关于您正在使用的使用简洁语法的相关子查询的行为。换句话说,就是

localField
&
foreignField
+
pipeline
的组合使用。您可以认为在子管道的开头添加一个带有
$match
$eq
阶段。但是,您的
storeIds
是一个数组,因此
$eq
不起作用,需要使用
$in

所以你可以做如下的事情:

  1. let
    中使用
    $lookup
    来分配变量,例如命名为
    sids
  2. 删除
    localField
    foreignField
    选项
  3. 用您的
    $search
  4. 开始您的管道
  5. $match
     之后放置一个带有 
    $in
    sids
    $search
  6. 舞台
{
    $lookup: {
      from: "location_view_for_search",
      let: {
        sids: "$storeIds"
      },
      as: "store_details",
      pipeline: [
        {
          $search: {
            // your $search here
          }
        },
        {
          "$match": {
            $expr: {
              $in: [
                "$location_number",
                "$$sids"
              ]
            }
          }
        }
      ]
    }
  }

Mongo Playground 演示完整语法。该查询不会在 Playground 中运行,因为那里不支持

$search

© www.soinside.com 2019 - 2024. All rights reserved.