是否可以在从mongoDB检索之前转换数据?

时间:2017-08-30 10:27:56

标签: mongodb highlighting teaser

假设我有一个只有一个字段BlogText的集合。当用户搜索某个字词时,如果该字词出现在BlogText中,我想:

  1. 在匹配的单词之前只检索10个单词,在匹配的查询之后检索10个单词,然后是省略号。
  2. 此外,我想将Matched word替换为<b>Matched word</b>
  3. 例如,如果搜索到的查询是 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点)。

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" ] }
                    }}            
                ]}
            }
        } 
    }}
]);