Для получения полного доступа
зарегистрируйтесь.
RSS

Все сниппеты с тэгами «JavaScript, mongodb»



Stephen Berezuev
  • Репутация: 5
  • Сниппеты: 3
  • Ревизии: 1

В MongoDB отвратительный полнотекстовый поиск. Для индексации и поиска можно использовать Sphinxsearch. В интернете есть несколько вариантов, как это сделать (при помощи PHP, mongoexport --type=csv, etc).

Но, как показала практика, когда колличество документов в коллекции измеряется миллионами и они собираются из разных источников, перечисленные методы либо вообще не работают (сфинкс ломается о различные спец.символы), либо просто виснут. Самым быстрым и надежным способом в итоге оказалось генерировать индекс силами самого сфинкса.

Ниже пример. Сразу предупрежу, что я специально отказался от использования XML DOM в пользу скорости.

//echo header
print("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
    + "<sphinx:docset>\n"
    + "    <sphinx:schema>\n"
    + "      <sphinx:field name=\"content\"/>\n"
    + "    </sphinx:schema>\n");
    
//echo posts
db.posts.find().forEach( function(post) {
	print('<sphinx:document id="' + post._id.valueOf() + "\">\n"
    + '    <content>' + doc.content.toString().replace(/[><]/g,'') + "</first_name>\n" //обязательно убирайте символы < и >
    + "</sphinx:document>\n");
}

print("</sphinx:docset>");

Если в _id у вас не только цифры (а по умолчанию, если вы ничего не присваиваете в _id, это так и будет), то стоит добавить счетчик i++ вместо post._id.valueOf()

Ну и, исходник в сфинксе:

source sourcename
{
    type = xmlpipe2
    xmlpipe_command = mongo databasename --quiet /path/to/jsfile.js
    xmlpipe_field_string = content
}
Gravatar image
veloriba
  • Репутация: 2
  • Сниппеты: 1
  • Ревизии: 0

Запрос добавляет поле типа ISODate к уже имеющимуся таймштампу типа интеджер:

{

"_id" : 100500,
"timestamp" : 1418992107,
"timestamp_human" : ISODate("2014-08-12T05:41:39.000Z")

}

db.mycollection.find().forEach(
    function(doc){
        doc.timestamp_human = new Date(parseInt(doc.timestamp + "000"))
        print(doc) 
    }
)