В 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
}
Благодарю автора zular за данный скрипт. Хотел написать коммент, но нажал чтото не то :) В общем, чтобы класс таки удалялся, на 6 строке лучше сравнивать в виде ">" а не ">=" ибо в нашем случае $(window).scrollTop() всегда >= 0
Здравствуйте, столкнулся с задачей фиксации меню при скролле страницы, был найден скрипт на просторах интернета, который решил мою задачу. Я его немного изменил под свои нужды.
Зависимости:
Классы:
Преимущества скрипта:
// --- affix top menu script ---
$(() => {
let target = $('.nav-afix');
let startPosition = target.offset().top;
$(window).scroll(() => {
if ($(window).scrollTop() > startPosition) {
if (!target.hasClass()) {
target.addClass('affix')
};
} else {
target.removeClass('affix')
};
});
});
Здравствуйте, столкнулся с задачей фиксации меню при скролле страницы, был найден скрипт на просторах интернета, который решил мою задачу. Я его немного изменил под свои нужды.
Зависимости:
Классы:
Преимущества скрипта:
// --- affix top menu script ---
$(() => {
let target = $('.nav-afix');
let startPosition = target.offset().top;
$(window).scroll(() => {
if ($(window).scrollTop() >= startPosition) {
if (!target.hasClass()) {
target.addClass('affix')
};
} else {
target.removeClass('affix')
};
});
});
Код https://github.com/lnked/gulp
По правде coffescript я тоже не использую. Но не об этом ))) Статья для новичков и для тех, кто стремится изучить эту тему. Для бывалых скорее всего покажется простыми брызгами слюней от "открытия америки".
Есть такая замечательная штука Gulp. Легко гуглится. В кратце это серверный комбайн расширяемый плагинами. Код который привел ниже запускается в командной строке одной лишь командой # gulp При этом он делает следующее
Вот такие вот задачки иногда попадаются на собеседовании на должность Frontend Web Developer: Написать парсер математических выражений методом рекурсивного спуска. Должны поддерживаться операции сложения, вычитания, умножения, деления, возведения в степень, а также скобки. Хоть задача и тривиальная, но мне стало интересно ваше мнение, как подобная задача коррелирует с должностью? Видимо оценить уровень владения языком?
P.S.: Известные проблемы данной реализации:
var TokenType = {
Empty: { name: "Empty" },
Number: { name: "Number", expectAfter: [ "Empty", "Operator" ] },
Operator: { name: "Operator", expectAfter: [ "Number", "Expression" ] },
Expression: { name: "Expression", expectAfter: [ "Empty", "Operator" ] }
};
var Operator = [
{ operator: "^", priority: 3, eval: function(a,b) { return Math.pow(a,b); } },
{ operator: "*", priority: 2, eval: function(a,b) { return a*b; } },
{ operator: "/", priority: 2, eval: function(a,b) { return a/b; } },
{ operator: "+", priority: 1, eval: function(a,b) { return a+b; } },
{ operator: "-", priority: 1, eval: function(a,b) { return a-b; } }
];
function Evaluator()
{
}
Evaluator.prototype = {
eval: function(str) {
var tokens = [];
while(str !== "") {
var token = this.extractNumber(str, tokens.length === 0);
if (token === null) {
token = this.extractOperator(str);
}
if (token === null) {
token = this.extractExpression(str);
}
if (token === null) {
throw Error('Token unexpected '+str);
}
this.assert(tokens[tokens.length - 1], token);
tokens.push(token);
str = str.substr(token.rawValue.length);
}
if (tokens.length === 0) return null;
if (tokens[tokens.length - 1].type === TokenType.Operator) {
throw new Error('Invalid formula');
}
return this.processTokens(tokens);
},
processTokens: function(tokens) {
var processTokens = [];
while (tokens.length > 1) {
var maxPriority = tokens.filter(function(t) {
return t.type === TokenType.Operator;
}).map(function(t) {
return t.operator.priority;
}).reduce(function (acc, v) {
return v > acc ? v : acc;
}, Number.MIN_VALUE);
for (var i = 0; i < tokens.length; i++) {
if (tokens[i].type === TokenType.Operator && tokens[i].operator.priority === maxPriority) {
var leftOperand = processTokens.pop();
var operator = tokens[i].operator;
var rightOperand = tokens[i + 1];
var evalValue = operator.eval(Number(leftOperand.value), Number(rightOperand.value));
processTokens.push({"value": evalValue, "rawValue": evalValue, "type": TokenType.Number});
i++;
} else {
processTokens.push(tokens[i])
}
}
tokens = processTokens;
processTokens = [];
}
if (tokens.length === 0) {
throw new Error('Unexpected error');
}
return tokens[0].value;
},
assert: function(prevToken, currentToken)
{
if (prevToken == undefined && currentToken.type.expectAfter.indexOf("Empty") !== -1)
return;
if (prevToken !== undefined && currentToken.type.expectAfter.indexOf(prevToken.type.name) !== -1)
return;
throw Error("Invalid formula");
},
clear: function(str)
{
return str.replace(/\s+/g,"");
},
extractNumber: function(str, allowMinus)
{
var regExp = new RegExp("^"+(allowMinus ? "[\-]?" : "")+"[0-9]*(?:[.][0-9]+)?","g");
var match = regExp.exec(str);
if (match === null || match.length === 0 || match[0].length === 0) return null;
return { "value": match[0], "rawValue": match[0], "type": TokenType.Number };
},
extractOperator: function(str)
{
for(var i = 0; i < Operator.length; i++)
{
var regExp = new RegExp("^"+ RegExp.escape(Operator[i].operator)+"","g");
var match = regExp.exec(str);
if (match !== null && match.length > 0)
return { "value": match[0], "rawValue": match[0], "operator": Operator[i], "type": TokenType.Operator }
}
return null;
},
extractExpression: function(str)
{
var regExp = /^(\(.*\))/g;
var match = regExp.exec(str);
if (match === null || match.length < 2) return null;
var brackets = ['('];
var value = match[0];
for (var i = 1; i < value.length; i++)
{
if (value[i] === '(') {
brackets.push('(');
}
if (value[i] === ')') {
brackets.pop();
}
if (brackets.length === 0) {
break;
}
}
value = value.substr(1, i-1);
if (value === "") {
throw new Error("Invalid formula");
}
var e = new Evaluator();
return { "value": e.eval(value), "rawValue": "("+value+")", "type": TokenType.Expression };
}
};
if (RegExp.escape === undefined) {
RegExp.escape= function(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
}
Нужно загрузить файл на сервер, без перезагрузки страницы? Видел много костылей на эту тему, вот вам простой вариант, который использую сам)
var form = new FormData(document.getElementById('идентификатор формы'));
$.ajax({
url: "/upload.php",
type: "POST",
data: form,
enctype: 'multipart/form-data',
processData: false,
contentType: false,
success: function (data) {
// здесь обработка ответа от сервер
}
});
1) Сложность пароля Качество и сложность пароля - мнение часто субъективно. Но данный сниппет хорошее начало )
^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$
2) Проверка на HEX цвет.
\#([a-fA-F]|[0-9]){3, 6}
3) Проверка email. Данный пункт хорошее начало холивара!
/[A-Z0-9._%+-]+@[A-Z0-9-]+.+.[A-Z]{2,4}/igm
Иногда, что бы сделать сайт максимально быстрым для пользователя (или хотя бы сделать такое впечатление), можно прибегать к таким средствам как в этом сниппете. Суть этих строк в том, что страница на которую ведёт ссылка -- начинает загружаться еще до того как пользователь на нее нажмёт (в тот период как только клавиша миши начала опускаться, а курсор указывает на ссылку), это ускорит загрузку страниц на 50ms.
document.onmousedown = function(e) {
e.target.click();
}
Методы, которые были в балалайке, устарели. Теперь bala.js рулит.
$=function(d,e,c,f,g){c=function(a,b){return new f(a,b)};f=function(a,b){e.push.apply(this,a?a.nodeType||a==window?[a]:""+a===a?/</.test(a)?((g=d.createElement(b||"q")).innerHTML=a,g.children):(b&&c(b)[0]||d).querySelectorAll(a):/f/.test(typeof a)?/c/.test(d.readyState)?a():d.addEventListener("DOMContentLoaded",a):a:e)};c.fn=f.prototype=e;c.one=function(a,b){return c(a,b)[0]||null};return c}(document,[]);