假设我有一个只有一个字段BlogText
的集合。当用户搜索某个字词时,如果该字词出现在BlogText
中,我想:
Matched word
替换为<b>Matched word</b>
例如,如果搜索到的查询是 1500 ,我想要检索以下内容:
... has been the industry's standard dummy text ever since the <b>1500<b>s, when an unknown printer took a galley of type and ...
鉴于BlogText
中的原始文字是:
Lorem Ipsum只是印刷和排版行业的虚拟文本。自16世纪以来,Lorem Ipsum一直是业界标准的虚拟文本,当时一台未知的打印机采用了类型的厨房,并将其拼凑成一本类型的样本。它不仅存在了五个世纪,而且还延续了电子排版,基本保持不变。它在20世纪60年代随着包含Lorem Ipsum段落的Letraset表格的推出而普及,最近还推出了包括Lorem Ipsum版本在内的桌面出版软件Aldus PageMaker。
我知道这也可以在服务器上完成,但我想避免检索我不需要的数据(参考第1点)。
答案 0 :(得分:2)
您可以使用aggregation返回长文本的子字符串。
假设您需要围绕匹配术语第一次出现的子字符串,并且空格用作单词分隔符,则管道可以是这样的:
db.collection.aggregate([
{ $match: { BlogText:/1500/ } },
{ $project: {
match: {
$let: {
vars: { pos: { $indexOfCP: [ "$BlogText", "1500" ] }},
in: { $concat: [
{ $reduce: {
input: { $slice: [
{ $split: [
{ $substrCP: [ "$BlogText", 0, "$$pos" ] },
" "
]},
-10
]},
initialValue: "",
in: { $concat : [ "$$value", " ", "$$this" ] }
}},
{ $reduce: {
input: { $slice: [
{ $split: [
{ $substrCP: [ "$BlogText", "$$pos", { $strLenCP: "$BlogText" } ] },
" "
]},
10
]},
initialValue: "",
in: { $concat : [ "$$value", " ", "$$this" ] }
}}
]}
}
}
}}
]);