Заказать поиск по списку по совпадению - PullRequest
0 голосов
/ 01 апреля 2020

Я делаю поисковик с Angularjs и хочу показать результаты по совпадению, как поиск в Google, но в настоящее время я получаю только значения из источника данных, и это не ordening, у меня есть это код фильтра:

var datoFiltro = this.filter;
var dataFull = this.data;
var filteredTitle = dataFull.filter(function(item) {
  if (datoFiltro && datoFiltro.length) {
    var words = datoFiltro.split(" ").filter(function(word) {
      return word.length >= 3; 
    });
    var pattern = "(?<=^|\\s)(" + words.join("|") + ")";
    var re = new RegExp(pattern, "gi");
    return re.test(item.titulo);
  }
  return true;
});
var filteredCat = dataFull.filter(function(item) {
  if (datoFiltro && datoFiltro.length) {
    var words = datoFiltro.split(" ").filter(function(word) {
      return word.length >= 3; 
    });
    var pattern = "(?<=^|\\s)(" + words.join("|") + ")";
    var re = new RegExp(pattern, "gi");
    return re.test(item.nombreCategoria);
  }
  return true;
});
var filteredDesc = dataFull.filter(function(item) {
  if (datoFiltro && datoFiltro.length) {
    var words = datoFiltro.split(" ").filter(function(word) {
      return word.length >= 3; 
    });
    var pattern = "(?<=^|\\s)(" + words.join("|") + ")";
    var re = new RegExp(pattern, "gi");
    return re.test(item.descripcion);
  }
  return true;
});

var resultado = filteredCat.concat(filteredTitle, filteredDesc);
var q = [...new Map(resultado.map(obj => [JSON.stringify(obj), obj])).values()];
return q;

Тем не менее, этот поиск будет хорошо выполнен с использованием этого примера данных:

dataFull =[
          {
            id: 721,
            titulo: "Cotizador Gastos Médicos Bx+ 2019",
            descripcion: "Cotizador Gastos Médicos Bx+ Tarifas 2019",
            updateDate: "2020-03-25 14:30:22.0",
            idCategoria: "1",
          },
          {
            id: 88,
            titulo: "Cotizador GMM Colectivo",
            descripcion: "Cotizador GMM Colectivo",
            updateDate: "2020-03-25 14:27:43.0",
            idCategoria: "1",
          },
          {
            id: 302,
            titulo: "Cotizador AP Escolar",
            descripcion: "Cotizador Accidentes Personales Escolar",
            updateDate: "2020-03-25 14:26:48.0",
            idCategoria: "1",
          },
          {
            id: 865,
            titulo: "Cotizador Únikuz Bx+",
            descripcion: "Cotizador Únikuz Bx+",
            updateDate: "2020-03-19 13:14:01.0",
            idCategoria: "1",
          },
          {
            id: 381,
            titulo: "Cotizador Premia Bx+",
            descripcion: "Cotizador Premia Bx+",
            updateDate: "2020-01-02 12:27:43.0",
            idCategoria: "1",
          },
          {
            id: 89,
            titulo: "Cotizador Vida Grupo",
            descripcion: "Cotizador Vida Grupo",
            updateDate: "2019-12-26 17:20:00.0",
            idCategoria: "1",
          },
        ];

Если я ищу "bx + únikuz", он возвращает 3 строки, но моя цель (2 совпадения) находится в 2-й ряд:

enter image description here

Как упорядочить эти результаты по совпадениям?

ОБНОВЛЕНИЕ :

Я изменил код на:

getData: function() {
  var datoFiltro = this.filter;
  var dataFull = this.data;
  var query1 = $filter('filter')(this.data, this.filter);
  var acumuladoQuery = [];
  if (query1.length > 0) {

  } else {
    var palabras = datoFiltro.split(/\s+/).filter(function(word) {
      return word.length >= 3;
    });

    for (var x = 0; x < dataFull.length; x++) {
      var conteo = 0;
      for (var y = 0; y < palabras.length; y++) {
        var x1 = dataFull[x];
        var y1 = palabras[y];
        if (dataFull[x].nombreCategoria.toUpperCase().includes(palabras[y].toUpperCase()) ||
          dataFull[x].titulo.toUpperCase().includes(palabras[y].toUpperCase()) ||
          dataFull[x].descripcion.toUpperCase().includes(palabras[y].toUpperCase())) {
          acumuladoQuery.push(dataFull[x]);
        }
        if (conteo == palabras.length) {
          return acumuladoQuery;
        }
      }
    }
  }
  var resultado = query1.concat(acumuladoQuery);
  var q = [...new Map(resultado.map(obj => [JSON.stringify(obj), obj])).values()];
  return q;
}

Теперь я получаю массив с вхождениями, как его отсортировать? Пример:

q = [
{Array1},
{Array3},
{Array3},
{Array3},
{Array2},
{Array2}
];

Я хочу получить:

q1 = [
{Array3},
{Array2},
{Array1}
];

1 Ответ

0 голосов
/ 02 апреля 2020

Я решил эту проблему, и я делюсь ею, может быть, кто-то хочет сделать что-то подобное:

Мой окончательный код таков:

getData: function () {
                var datoFiltro = this.filter;
                var dataFull = this.data;
                var query1 = $filter('filter')(this.data, this.filter);
                var acumuladoQuery =[];
                if (query1.length>0){
                    acumuladoQuery=query1;
                } else{                 
                    var palabras = datoFiltro.split(/\s+/).filter(function (word) {
                        return word.length >= 3; 
                    });

                    for (var x=0; x<dataFull.length; x++ ){
                        var conteo = 0;
                        for (var y=0; y<palabras.length; y++){
                            var x1 = dataFull[x];
                            var y1 = palabras[y];
                            if(dataFull[x].nombreCategoria.toUpperCase().includes(palabras[y].toUpperCase())
                                    ||dataFull[x].titulo.toUpperCase().includes(palabras[y].toUpperCase())
                                    ||dataFull[x].descripcion.toUpperCase().includes(palabras[y].toUpperCase())){
                                acumuladoQuery.push(dataFull[x]);
                            }
                            if(conteo == palabras.length){
                                return acumuladoQuery;   
                           }
                        }
                    } 
                }               
                var resultado = acumuladoQuery;
                let count = resultado.reduce((res, val) => {
                      if(res[val.id]) {
                        res[val.id]++;
                      } else {
                        res[val.id] = 1;
                      }
                      return res;
                    }, {});             
                let output= Object.entries(count)
                  .sort((a, b) => b[1]-a[1]) 
                  .map(function(obj){
                    var rObj = [];
                    for (var x=0; x<resultado.length; x++){                     
                        if(resultado[x].id==obj[0]){
                            if(rObj.includes(resultado[x])){                                
                            } else{
                                rObj.push(resultado[x]);
                            }
                        }
                    }
                    return rObj;
                  }); 
                var lista = [];
                for (var x=0; x<output.length; x++){
                    lista[x]={};
                    lista[x]=output[x][0];
                }
                return lista;
            },

Сначала я ищу с оригинальным и простым фильтр:

var query1 = $filter('filter')(this.data, this.filter);

Если у меня нет результатов, я произвел разделение по словам с минимальными 3 буквами

if (query1.length>0){
                    acumuladoQuery=query1;
                } else{                 
                    var palabras = datoFiltro.split(/\s+/).filter(function (word) {
                        return word.length >= 3; 
                    });

Я проверяю каждую строку моего исходного набора данных и мой новый результат разделения тогда я проверяю, есть ли у каждого элемента мое слово

for (var x=0; x<dataFull.length; x++ ){
                    var conteo = 0;
                    for (var y=0; y<palabras.length; y++){
                        var x1 = dataFull[x];
                        var y1 = palabras[y];
                        if(dataFull[x].nombreCategoria.toUpperCase().includes(palabras[y].toUpperCase())
                                ||dataFull[x].titulo.toUpperCase().includes(palabras[y].toUpperCase())
                                ||dataFull[x].descripcion.toUpperCase().includes(palabras[y].toUpperCase())){
                            acumuladoQuery.push(dataFull[x]);
                        }
                        if(conteo == palabras.length){
                            return acumuladoQuery;   
                       }
                    }
                } 
            }               

Теперь у меня есть новый набор данных, который включает мои слова, я получаю частоту, как следует

var resultado = acumuladoQuery;
                let count = resultado.reduce((res, val) => {
                      if(res[val.id]) {
                        res[val.id]++;
                      } else {
                        res[val.id] = 1;
                      }
                      return res;
                    }, {});     

Затем я упорядочиваю по частота (потому что у меня есть повторяющиеся значения, которые включают мои слова, больше повторение означает возможную цель пользователя) после упорядочения я получаю объект (объект объектов) построчно (я не нашел способа создать простой arrraylist)

let output= Object.entries(count)
                  .sort((a, b) => b[1]-a[1]) 
                  .map(function(obj){
                    var rObj = [];
                    for (var x=0; x<resultado.length; x++){                     
                        if(resultado[x].id==obj[0]){
                            if(rObj.includes(resultado[x])){                                
                            } else{
                                rObj.push(resultado[x]);
                            }
                        }
                    }
                    return rObj;
                  }); 

Наконец-то я создаю простой массив и возвращаю его

var lista = [];
                for (var x=0; x<output.length; x++){
                    lista[x]={};
                    lista[x]=output[x][0];
                }
                return lista;

Надеюсь, возможно, этот код кому-нибудь поможет, спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...