Implementando searchLikeBy en MongoDB con Jmoordbcore 1/3

aristides villarreal - Nov 23 '23 - - Dev Community

En muchas ocasiones necesitamos realizar consultas mediante expresiones regulares que se unen con otras condiciones de búsqueda en la que se necesita utilizar paginación y ordenación.

Vídeo de muestra Búsquedas con expresiones regulares en MongoDB mediante Jmoordbcore
En JmoordbCore es posible utilizar la anotación @SearchByLike, para generar consultas utilizando expresiones regulares combinadas. Por ejemplo:

@SearchLikeBy(caseSensitive = CaseSensitive.NO, typeOrder = TypeOrder.ASC, likeByType = LikeByType.ANYWHERE)
    public List<Tarjeta> searchLikeByTarjeta(String tarjeta, Search search);
Enter fullscreen mode Exit fullscreen mode

En este ejemplo utilizaremos un Microservicio que utiliza https://microprofile.io/ con una base de datos MongoDB, que se comunica mediante Jmoordbcore.

Image description

Se cuenta con documentos que almacenan información sobre tarjetas con atributos similares a estos

Image description

Las interfaces de usuario se desarrollan utilizando Jakarta Faces con Primefaces, como se muestra en la siguiente figura:

Image description

Pasos:

  1. Cree un proyecto Jakarta EE con Payara Starter https://start.payara.fish/
  2. Agregue la dependencia de jmoordbcore
  <version.jmoordbcore>1.0.0.b-7</version.jmoordbcore>

 <dependency>
     <groupId>com.github.avbravo</groupId>
     <artifactId>jmoordb-core</artifactId>
     <version>${version.jmoordbcore}</version>
 </dependency>

 <repositories>
   <repository>
      <id>jitpack.io</id>
     <url>https://jitpack.io</url>
  </repository>
 </repositories>
Enter fullscreen mode Exit fullscreen mode
  1. Agrega propiedades de conexión a la base de datos en el archivo microprofile-config.properties

mongodb.uri=mongodb://localhost:27017
#-- Database de configuración
mongodb.jmoordb= configurationjmoordbdb

#-- Database History
mongodb.databasehistory=historydb

#-- Database
mongodb.database=accreditation
mongodb.database1=sft
mongodb.database2=practicadb

Enter fullscreen mode Exit fullscreen mode
  1. Defina la entidad Tarjeta que representa un documento de la colección
@Entity
public class Tarjeta {

    @Id(autogeneratedActive = AutogeneratedActive.ON)
    private Long idtarjeta;
    @Column
    private String tarjeta;
    @Column
    private String descripcion;

    @ViewReferenced(from = "user", localField = "iduser")
    List<UserView> userView;

    @Column
    private Date fechainicial;
    @Column
    private Date fechafinal;
    @Referenced(from = "icono", localField = "idicono", commentary = "Esta asociado a la prioridad")
    private Icono icono;
    @Referenced(from = "tipotarjeta", localField = "idtipotarjeta", commentary = "Ayuda para la implementación de Deep Learning")
    private Tipotarjeta tipotarjeta;

    @Column
    private Long idsprint;

    @Column
    private Long idproyecto;

    @Column
    private Boolean backlog;

    @Column(commentary = "alta,baja,media")
    private String prioridad;

    @Column
    private String estimacion;

    @Column(commentary = "pendiente,progreso,finalizado")
    private String columna;
    @Column
    private Boolean active;

    @Embedded
    List<Tarea> tarea;

    @Embedded
    List<Comentario> comentario;

    @Embedded
    List<Etiqueta> etiqueta;

    @Embedded
    List<Archivo> archivo;

    @Embedded
    List<Impedimento> impedimento;

    @Column(commentary = "true cuando la crea un colaborador que no pertenece al proyecto y es un proyecto publico")
    private Boolean foreaneo;

    @Embedded
    List<ActionHistory> actionHistory;

    public Tarjeta() {
    }

...
}
Enter fullscreen mode Exit fullscreen mode
  1. Defina el repositorio TarjetaRepository.java, con métodos para contar los documentos y realizar búsquedas combinando expresiones regulares con otros filtros.
@Repository(database = "{mongodb.database1}", entity = Tarjeta.class)
public interface TarjetaRepository extends CrudRepository<Tarjeta, Long> {

 @SearchCountLikeBy(caseSensitive = CaseSensitive.NO, likeByType = LikeByType.ANYWHERE)
    public Long searchCountLikeByTarjeta(String tarjeta, Search search);

    @SearchCountLikeBy(caseSensitive = CaseSensitive.NO, likeByType = LikeByType.ANYWHERE)
    public Long searchCountLikeByDescripcion(String descripcion, Search search);

 @SearchLikeBy(caseSensitive = CaseSensitive.NO, typeOrder = TypeOrder.ASC, likeByType = LikeByType.ANYWHERE)
    public List<Tarjeta> searchLikeByTarjeta(String tarjeta, Search search);

    @SearchLikeBy(caseSensitive = CaseSensitive.NO, typeOrder = TypeOrder.ASC, likeByType = LikeByType.ANYWHERE)
    public List<Tarjeta> searchLikeByDescripcion(String descripcion, Search search);

}
Enter fullscreen mode Exit fullscreen mode
  1. Cree una clase controladora llamada TarjetaController.java
@Path("tarjeta")
@Tag(name = "Información del tarjeta", description = "End-point para entidad Tarjeta")
@RolesAllowed({"admin"})
public class TarjetaController {


@GET
@Path("searchcountlikebytarjeta")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public  Long searchCountLikeByTarjeta(@QueryParam("tarjeta") String tarjeta, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size) {
      Long result = 0L;
        try {
            Search search = DocumentUtil.convertForLookup(filter, sort, page, size);
           result= tarjetaRepository.searchCountLikeByTarjeta(tarjeta, search);
        } catch (Exception e) {
            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }
        return result;
    }


@GET
@Path("searchcountlikebydescripcion")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public  Long searchCountLikeByDescripcion(@QueryParam("descripcion") String descripcion, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size) {
       Long result = 0L;
        try {
            Search search = DocumentUtil.convertForLookup(filter, sort, page, size);
           result= tarjetaRepository.searchCountLikeByDescripcion(descripcion, search);
        } catch (Exception e) {
            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }
        return result;
    }

@GET
@Path("likebytarjetasearch")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public List<Tarjeta> searchLikeByTarjeta(@QueryParam("tarjeta") String tarjeta, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size) {
        List<Tarjeta> suggestions = new ArrayList<>();
        try {
            Search search = DocumentUtil.convertForLookup(filter, sort, page, size);
            suggestions = tarjetaRepository.searchLikeByTarjeta(tarjeta, search);
        } catch (Exception e) {
            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }
        return suggestions;
    }


@GET
@Path("likebydescripcionsearch")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public List<Tarjeta> searchLikeByDescripcion(@QueryParam("descripcion") String descripcion, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size) {
        List<Tarjeta> suggestions = new ArrayList<>();
        try {
            Search search = DocumentUtil.convertForLookup(filter, sort, page, size);
            suggestions = tarjetaRepository.searchLikeByDescripcion(descripcion, search);
        } catch (Exception e) {
            MessagesUtil.error(MessagesUtil.nameOfClassAndMethod() + "error: " + e.getLocalizedMessage());
        }
        return suggestions;
    }
}
Enter fullscreen mode Exit fullscreen mode

Creando el Cliente
Pasos:

  1. Cree un proyecto nuevo con Cree un proyecto Jakarta EE con Payara Starter https://start.payara.fish/

  2. Agregue al archivo microprofile-config.properties restclient

com.sft.restclient.TarjetaRestClient/mp-rest/url=http://localhost:9002/accreditation/api/
Enter fullscreen mode Exit fullscreen mode
  1. Cree la entidad tarjeta que definió en el microservicio.

  2. Cree las interfaces para el endpoint tarjeta

@RegisterRestClient()
@Path("/tarjeta")

public interface TarjetaRestClient {
@GET
@Path("likebytarjetasearch")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
List<Tarjeta> searchLikeByTarjeta(@QueryParam("tarjeta") String tarjeta, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size);

@GET
@Path("likebydescripcionsearch")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
List<Tarjeta> searchLikeByDescripcion(@QueryParam("descripcion") String descripcion, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size);


@GET
@Path("searchcountlikebytarjeta")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public  Long searchCountLikeByTarjeta(@QueryParam("tarjeta") String tarjeta, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size);


@GET
@Path("searchcountlikebydescripcion")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public  Long searchCountLikeByDescripcion(@QueryParam("descripcion") String descripcion, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("page") Integer page, @QueryParam("size") Integer size);

Enter fullscreen mode Exit fullscreen mode
  1. Cree la interface TarjetaServices
public interface TarjetaServices {

public List<Tarjeta> searchLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size);
    public Long searchCountLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size);

    public List<Tarjeta> searchLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size);
        public Long searchCountLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size);

}


Enter fullscreen mode Exit fullscreen mode
  1. Cree la implementación
@ApplicationScoped
public class TarjetaServicesImpl implements TarjetaServices {


@Inject
TarjetaRestClient tarjetaRestClient;



    @Override
    public List<Tarjeta> searchLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size) {
        List<Tarjeta> tarjetaList = new ArrayList<>();
        try {
            tarjetaList = tarjetaRestClient.searchLikeByTarjeta(tarjeta,
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size);
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return tarjetaList;
    }




    @Override
    public Long searchCountLikeByTarjeta(String tarjeta, Bson filter, Document sort, Integer page, Integer size) {
        Long result = 0L;
        try {
            result = tarjetaRestClient.searchCountLikeByTarjeta(tarjeta,
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size);
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }


    @Override
    public List<Tarjeta> searchLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size) {
        List<Tarjeta> tarjetaList = new ArrayList<>();
        try {
            tarjetaList = tarjetaRestClient.searchLikeByDescripcion(descripcion,
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size);
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return tarjetaList;
    }



    @Override
    public Long searchCountLikeByDescripcion(String descripcion, Bson filter, Document sort, Integer page, Integer size) {
        Long result = 0L;
        try {
            result = tarjetaRestClient.searchCountLikeByDescripcion(descripcion,
                    EncodeUtil.encodeBson(filter),
                    EncodeUtil.encodeBson(sort),
                    page, size);
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }


}

Enter fullscreen mode Exit fullscreen mode
  1. Diseñe la interface de usuario con Jakarta Server Faces y Primefaces para realizar búsquedas, quedando de la siguiente manera:

Interface de usuario

Entre los elementos usados se encuentran:

  • inputText

  • selectOneMenu

  • dataTable

Se usara un datable, con columnas y componentes que no se muestran completamente en la siguiente sección:

<p:dataTable var="item" value="#{buscadorTarjetasFaces.tarjetaLazyDataModel}"
 binding="#{buscadorTarjetasFaces.dataTable}"
 id="dataTable"
widgetVar="widgetVardataTable"
lazy="true"
paginator="true"
rows="#{buscadorTarjetasFaces.rowPageSmall.get()}"                                           paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
paginatorPosition="both"
reflow="true"
rowKey="#{item.idtarjeta}"
selection="#{buscadorTarjetasFaces.tarjetaSelected}"
rowSelectMode="add">
<p:column class="column2">
 <p:rowToggler/>
</p:column>
 <p:column class="column8" headerText="#{msg['field.idtarjeta']}">
 <p:outputLabel value="#{item.idtarjeta}"/>
</p:column>
...
Enter fullscreen mode Exit fullscreen mode

Formulario de búsquedas

  1. Cree la clase BuscadorTarjetasFaces
@Named
@ViewScoped
@Data
public class BuscadorTarjetasFaces implements Serializable, JmoordbCoreXHTMLUtil, IPaginator, SprintFacesServices {


@Inject
TarjetaServices tarjetaServices;


Enter fullscreen mode Exit fullscreen mode

En el método init() se realizara la administración de la paginación insertando el siguiente codigo

this.tarjetaLazyDataModel = new LazyDataModel<Tarjeta>() {
    @Override
    public List<Tarjeta> load(int offset, int pageSize, Map<String, SortMeta> sortBy, Map<String, FilterMeta> filterBy) {

        if (textDescripcionToSearch == null || textDescripcionToSearch.equals("")) {
            totalRecords = tarjetaServices.searchCountLikeByTarjeta(textToSearch, paginator.getFilter(), paginator.getSort(), paginator.getPage(), rowPageSmall.get()).intValue();
        } else {
            if ((textToSearch == null || textToSearch.equals("")) && (textDescripcionToSearch != null || !textDescripcionToSearch.equals(""))) {

                totalRecords = tarjetaServices.searchCountLikeByDescripcion(textDescripcionToSearch, paginator.getFilter(), paginator.getSort(), paginator.getPage(), rowPageSmall.get()).intValue();
            } else {

                totalRecords = tarjetaServices.searchCountLikeByTarjeta(textToSearch, paginator.getFilter(), paginator.getSort(), paginator.getPage(), rowPageSmall.get()).intValue();
            }
        }


        List<Paginator> list = new ArrayList<>();
        if (!isRowPageSmall) {

            /**
             * Utiliza rowPage
             */
            list = processLazyDataModel(paginator, paginatorOld, offset, rowPage.get(), totalRecords, sortBy);

        } else {

            /**
             * Utiliza rowPageWithOverlayPanel para el OverlayPanel
             */
            list = processLazyDataModel(paginator, paginatorOld, offset, rowPageSmall.get(), totalRecords, sortBy);

        }
//

        paginator = list.get(0);
        paginatorOld = list.get(1);
        Pagination pagination = new Pagination();
        if (!isRowPageSmall) {

            paginator.setNumberOfPage(numberOfPages(totalRecords, rowPage.get()));
            pagination = new Pagination(paginator.getPage(), rowPage.get());
        } else {

            paginator.setNumberOfPage(numberOfPages(totalRecords, rowPageSmall.get()));
            pagination = new Pagination(paginator.getPage(), rowPageSmall.get());
        }

        List<Tarjeta> result = new ArrayList<>();

        if (textDescripcionToSearch == null || textDescripcionToSearch.equals("")) {
            result = tarjetaServices.searchLikeByTarjeta(textToSearch, paginator.getFilter(), paginator.getSort(), paginator.getPage(), rowPageSmall.get());
        } else {
            if ((textToSearch == null || textToSearch.equals("")) && (textDescripcionToSearch != null || !textDescripcionToSearch.equals(""))) {
                result = tarjetaServices.searchLikeByDescripcion(textDescripcionToSearch, paginator.getFilter(), paginator.getSort(), paginator.getPage(), rowPageSmall.get());
            } else {
              result = tarjetaServices.searchLikeByTarjeta(textToSearch, paginator.getFilter(), paginator.getSort(), paginator.getPage(), rowPageSmall.get());
            }
        }



        tarjetaLazyDataModel.setRowCount(totalRecords);

        PrimeFaces.current().executeScript("setDataTableWithPageStart()");
        PrimeFaces.current().executeScript("widgetVardataTable.getPaginator().setPage(0);");
        tarjetaList = result;

        return result;
    }

    @Override
    public int count(Map<String, FilterMeta> map) {

        return totalRecords;

    }

    @Override
    public String getRowKey(Tarjeta object) {
        if (object == null || object.getIdtarjeta() == null) {
            return "";
        }
        return object.getIdtarjeta().toString();
    }

    @Override
    public Tarjeta getRowData(String rowKey) {
        for (Tarjeta t : tarjetaList) {
            if (t != null) {
                if (t.getIdtarjeta().equals(rowKey)) {
                    return t;
                }
            }
        }
        return null;
    }

};

Enter fullscreen mode Exit fullscreen mode

En la siguiente sección se muestra los comportamientos de los eventos.

. . . . . . . . . . . . . .
Terabox Video Player