我有两个收藏: 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上的自动完成搜索来搜索位置
这是关于您正在使用的使用简洁语法的相关子查询的行为。换句话说,就是
localField
& foreignField
+ pipeline
的组合使用。您可以认为在子管道的开头添加一个带有 $match
的 $eq
阶段。但是,您的 storeIds
是一个数组,因此 $eq
不起作用,需要使用 $in
。
所以你可以做如下的事情:
let
中使用 $lookup
来分配变量,例如命名为 sids
localField
和 foreignField
选项$search
$match
之后放置一个带有
$in
和
sids
的
$search
{
$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
。