Можно ли преобразовать данные перед извлечением из mongoDB?

Допустим, у меня есть коллекция только с одним полем BlogText. Когда пользователь ищет слово и если это слово присутствует в BlogText, я хочу:

  1. Получить только 10 слов до совпадающего слова и 10 слов после совпавшего запроса, начиная с многоточия и заканчивая им.
  2. Также я хочу заменить 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 – это просто текст-пустышка, созданный для печати и набора текста. Lorem Ipsum был стандартным фиктивным текстом в отрасли с 1500-х годов, когда неизвестный печатник взял гранку шрифта и перемешал ее, чтобы сделать книгу образцов шрифтов. Он пережил не только пять столетий, но и скачок в электронный набор текста, оставаясь практически неизменным. Он был популяризирован в 1960-х годах с выпуском листов Letraset, содержащих отрывки из Lorem Ipsum, а совсем недавно - с программным обеспечением для настольных издательских систем, таким как Aldus PageMaker, включая версии Lorem Ipsum.

Я знаю, что это можно сделать и на сервере, но я хочу избежать получения данных, которые мне не нужны (ссылаясь на 1-й пункт).


person dasfdsa    schedule 30.08.2017    source источник
comment
Ваша единственная надежда - это структура агрегации, но я не уверен, что она достаточно продвинута.   -  person Sergio Tulentsev    schedule 30.08.2017
comment
но я хочу избежать извлечения данных, которые мне не нужны. -- Тогда почему вы предлагаете, чтобы база данных добавляла дополнительную разметку к результатам, которая увеличила бы количество байтов, которые ей нужно возвращать? ваш прикладной клиент??? Это было бы то, что мы называем противоречием. Это не работа баз данных, чтобы делать такие вещи (одна из причин, по которой стена функций, доступных в Oracle и т. д., отсутствует в MongoDB). Отмечайте совпадения после получения результатов с сервера базы данных. Вы должны помнить, какие термины вы просили, поэтому просто сопоставьте их и добавьте разметку.   -  person Neil Lunn    schedule 30.08.2017
comment
@SergioTulentsev Нет возможности сопоставления и замены регулярных выражений. И форсировать это через mapReduce было бы совершенно глупо.   -  person Neil Lunn    schedule 30.08.2017
comment
@NeilLunn Я согласен. Говоря это, я имел в виду свой 1-й пункт. BlogText может содержать 1000 слов, в то время как мне нужно только 11 или 13 даже после добавления тега b. Я буду редактировать.   -  person dasfdsa    schedule 30.08.2017


Ответы (1)


Вы можете вернуть подстроку длинного текста, используя агрегацию.

Assuming you need a substring around first occurrence of the matched term, and a space is used as a word delimiter, the pipeline can be like this:

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" ] }
                    }}            
                ]}
            }
        } 
    }}
]);
person Alex Blex    schedule 30.08.2017
comment
Спасибо. я постараюсь и дам вам знать - person dasfdsa; 30.08.2017