<commit_before>/*jslint node: true */
/*global require */

module.exports = function (util, events, http) {
    "use strict";

    var getFilterTypes = function (input) {
        var type = [];

        if (input !== undefined) {
            if (typeof input === "string") {
                type.push(input);
            } else if (Array.isArray(input)) {
                var isArrayOfStrings = input.every(function (element) {
                    return (typeof element === "string");
                });

                if (isArrayOfStrings) {
                    type = input;
                }
            }
        }

        return type;
    };

    var search = function () {
        events.EventEmitter.call(this);
    };

    util.inherits(search, events.EventEmitter);

    search.prototype.query = function (query) {
        var that = this;

        var filter = {
            "and" : [
            ]
        };

        var highlight = {
            "fields" : {
                "title" : {}
            },
            "encoder" : "html"
        };

        var requestData = {
            "query" : {
                "filtered" : {
                    query : {}
                }
            },
            "highlight" : highlight
        };

        var q = "";
        var qSuggestion = "";

        if (query.q !== undefined && typeof query.q === "string" && query.q !== "") {
            if (query.suggestion !== undefined) {
                q = "*";
                qSuggestion = query.q;
            } else {
                q = query.q;
                qSuggestion = q;
            }
        } else {
            q = "*";
            qSuggestion = "*";
        }

        requestData.query.filtered.query.query_string = {
            "query" : q,
            "default_operator" : "AND"
        };

        var priceMin;
        var priceMax;

        if (query["price-min"] !== undefined && typeof query["price-min"] === "string") {
            priceMin = query["price-min"].replace(/[^\d]/g, "");
            priceMin = parseInt(priceMin, 10);
        }

        if (query["price-max"] !== undefined && typeof query["price-max"] === "string") {
            priceMax = parseInt(query["price-max"].replace(/[^\d]/g, ""), 10);
            priceMax = parseInt(priceMax, 10);
        }

        if (! isNaN(priceMin) || ! isNaN(priceMax)) {
            var filterPrice = {};
            filterPrice.numeric_range = {};
            filterPrice.numeric_range.price = {};
            if (! isNaN(priceMin)) {
                filterPrice.numeric_range.price.from = priceMin;
            }

            if (! isNaN(priceMax)) {
                filterPrice.numeric_range.price.to = priceMax;
            }

            filter.and.push(filterPrice);
        }

        var filterTypesList = getFilterTypes(query.type);

        if (filterTypesList.length !== 0) {
            var filterTypes = {
                "terms" : {
                    "type" : filterTypesList
                }
            };

            filter.and.push(filterTypes);
        }

        if (filter.and.length !== 0) {
            requestData.query.filtered.filter = filter;
        }

        if (query.sort !== undefined) {
            if (query.sort === "price-min" || query.sort === "price-max") {
                var priceSort;

                if (query.sort === "price-min") {
                    priceSort = "asc";
                } else {
                    priceSort = "desc";
                }

                requestData.sort = [
                    {
                        "price" : {
                            "order" : priceSort,
                            "missing" : "_last",
                            "ignore_unmapped" : true
                        }
                    }
                ];
            }
        }

        if (query.suggestion !== undefined) {
            // see http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
            var qSuggestionEscaped = qSuggestion.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
            requestData.facets = {
                "title_suggestions":{
                    "terms" : {
                        "field" : "title.suggestions",
                        "regex" : "^" + qSuggestionEscaped.toLowerCase() + ".*",
                        "size" : 10
                    }<commit_msg>add facets to the query object<commit_after>/*jslint node: true */
/*global require */

module.exports = function (util, events, http) {
    "use strict";

    var getFilterTypes = function (input) {
        var type = [];

        if (input !== undefined) {
            if (typeof input === "string") {
                type.push(input);
            } else if (Array.isArray(input)) {
                var isArrayOfStrings = input.every(function (element) {
                    return (typeof element === "string");
                });

                if (isArrayOfStrings) {
                    type = input;
                }
            }
        }

        return type;
    };

    var search = function () {
        events.EventEmitter.call(this);
    };

    util.inherits(search, events.EventEmitter);

    search.prototype.query = function (query) {
        var that = this;

        var filter = {
            "and" : [
            ]
        };

        var highlight = {
            "fields" : {
                "title" : {}
            },
            "encoder" : "html"
        };

        var requestData = {
            "query" : {
                "filtered" : {
                    query : {}
                }
            },
            "highlight" : highlight
        };

        var q = "";
        var qSuggestion = "";

        if (query.q !== undefined && typeof query.q === "string" && query.q !== "") {
            if (query.suggestion !== undefined) {
                q = "*";
                qSuggestion = query.q;
            } else {
                q = query.q;
                qSuggestion = q;
            }
        } else {
            q = "*";
            qSuggestion = "*";
        }

        requestData.query.filtered.query.query_string = {
            "query" : q,
            "default_operator" : "AND"
        };

        var priceMin;
        var priceMax;

        if (query["price-min"] !== undefined && typeof query["price-min"] === "string") {
            priceMin = query["price-min"].replace(/[^\d]/g, "");
            priceMin = parseInt(priceMin, 10);
        }

        if (query["price-max"] !== undefined && typeof query["price-max"] === "string") {
            priceMax = parseInt(query["price-max"].replace(/[^\d]/g, ""), 10);
            priceMax = parseInt(priceMax, 10);
        }

        if (! isNaN(priceMin) || ! isNaN(priceMax)) {
            var filterPrice = {};
            filterPrice.numeric_range = {};
            filterPrice.numeric_range.price = {};
            if (! isNaN(priceMin)) {
                filterPrice.numeric_range.price.from = priceMin;
            }

            if (! isNaN(priceMax)) {
                filterPrice.numeric_range.price.to = priceMax;
            }

            filter.and.push(filterPrice);
        }

        var filterTypesList = getFilterTypes(query.type);

        if (filterTypesList.length !== 0) {
            var filterTypes = {
                "terms" : {
                    "type" : filterTypesList
                }
            };

            filter.and.push(filterTypes);
        }

        if (filter.and.length !== 0) {
            requestData.query.filtered.filter = filter;
        }

        if (query.sort !== undefined) {
            if (query.sort === "price-min" || query.sort === "price-max") {
                var priceSort;

                if (query.sort === "price-min") {
                    priceSort = "asc";
                } else {
                    priceSort = "desc";
                }

                requestData.sort = [
                    {
                        "price" : {
                            "order" : priceSort,
                            "missing" : "_last",
                            "ignore_unmapped" : true
                        }
                    }
                ];
            }
        }

        if (query.suggestion !== undefined) {
            // see http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
            var qSuggestionEscaped = qSuggestion.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
            requestData.facets = {
                "title_suggestions":{
                    "terms" : {
                        "field" : "title.suggestions",
                        "regex" : "^" + qSuggestionEscaped.toLowerCase() + ".*",
                        "size" : 10
                    }
                }
            };
        } else {
            requestData.facets = {
                "type" : {
                    "terms" : {
                        "field" : "type"
                    }
                },
                "make": {
                    "terms" : {
                        "field" : "make",
                        "size" : 10
                    }
                },
                "model" : {
                    "terms" : {
                        "field" : "model",
                        "size" : 10
                    }
                },
                "price" : {
                    "range" : {
                        "price" : [
                            { "from" : 0, "to" : 999999 },
                            { "from" : 1000000, "to" : 1999999 },
                            { "from" : 2000000, "to" : 2999999 },
                            { "from" : 3000000, "to" : 3999999 },
                            { "from" : 4000000, "to" : 4999999 },
                            { "from" : 5000000, "to" : 7999999 },
                            { "from" : 8000000, "to" : 8999999 },
                            { "from" : 9000000, "to" : 9999999 },
                            { "from" : 10000000 }
                        ]
                    }
                },
                "model_year": {
                    "terms" : {
                        "field" : "model_year",
                            "size" : 10
                    }
                },
                "where" : {
                    "terms" : {
                        "script_field" : "_source.user.address.locality + ' - ' + _source.user.address.region",
                        "size" : 10
                    }
{'fraction_non_alphanumeric': 0.13891784326731735, 'fraction_numerical': 0.014687766511892353, 'mean_word_length': 0.9901942296813124, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '508620', 'n_tokens_mistral': 2992, 'n_tokens_neox': 2665, 'n_words': 481}