Implementando searchLikeBy en MongoDB con Jmoordbcore 2/3
Published: 2023-11-24 16:27:20

Las expresiones regulares en Java se utilizan para validar patrones. En **MongoDB** se utiliza [$regex](https://www.mongodb.com/docs/manual/reference/operator/query/regex/).

A continuación se muestra la sintaxis y ejemplos de uso en **MongoDB**.

**Sintaxis:**

```shell
{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ "<field>": { "$regex": "pattern", "$options": "<options>" } }
{ <field>: { $regex: /pattern/<options> } }

```

- Ejemplo de consulta en MongoDB

```shell

db.tareas.find( { tarea: { $regex: /prueba$/ } } )

```

- Ejemplo de consulta en SQL utilizando Like.

```shell

SELECT * FROM Tarjetas WHERE tareas like "%prueba";

```

- Para realizar consultas que distingan entre mayúsculas y minúsculas. Se utiliza la opción **i**.

```shell
db.tareas.find( { tarea: { $regex: /^prueba/i } } )

```
- Para realizar consultas por coincidencias que inician por una letra, se utiliza m.

```shell
db.tareas.find( { tarea: { $regex: /^p/, $options: 'm' } } )

```

Jmoordbcore ofrece soporte para expresiones regulares mediante:

- @Regex 

- @RegexCount

- @SearchCountLikeBy

- @SearchLikeBy

## @Regex

La anotación @Regex, se emplea para realizar búsquedas basadas en expresiones regulares usando el comando $regex en MongoDB. 
```java
@Regex(where = "tarjeta .like. @tarjeta ",caseSensitive = CaseSensitive.NO,typeOrder = TypeOrder.ASC)
public List<Tarjeta> regex(String tarjeta);


``` 
## @RegexCount


La anotación @RegexCount, cuenta el número de documentos que coinciden con una expresión regular especificada.

La anotación devuelve un valor de tipo Long.

```java
@RegexCount(where = "tarjeta .like. @tarjeta",caseSensitive = CaseSensitive.YES)
public Long regexCountTarjeta(String tarjeta);
```


## @SearchCountLikeBy

La anotación @SearchCountLikeBy, cuenta el número de documentos que coinciden con una expresión regular especificada que utiliza Search, se asocia al uso de @SearchLikeBy.

La anotación devuelve un valor de tipo Long.

```java
 @SearchCountLikeBy(caseSensitive = CaseSensitive.NO,LikeByType.ANYWHERE)
   public Long serchCountLikeByTarjeta(String tarejeta, Search search);

```

## @SearchLikeBy

La anotación @SearchLikeBy permite definir las consultas basadas en el análisis del nombre de métodos, incorporando filtros, ordenación y paginación mediante un objeto de tipo Search. 

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

```
Estos fueron utilizados en el repositorio descrito en la parte 1 del tutorial anterior[Implementando searchLikeBy en MongoDB con Jmoordbcore 1/3](https://dev.to/avbravo/implementando-searchlikeby-en-mongodb-con-jmoordbcore-13-3odk).

## Jakarta Server Faces
Ahora definiremos en la pagina .xhtml, un inputText que realizara una búsqueda mediante expresión regular por el atributo tarjeta.

```html
 <p:inputText value="#{buscadorTarjetasFaces.textToSearch}"                                                       

id="inputTextToSearch" >
<p:ajax event="keyup" listener="#{buscadorTarjetasFaces.sugerirTarjetas}"                                                             

update=":form:growl, dataTable,inputTextDescripcionToSearch"
/>
</p:inputText>
```
Se observa que utilizamos _<p:ajax>_ para gestionar el evento **keyup** de manera que en la medida que el usuario escriba algo en la caja de texto deseamos realizar la búsqueda como una expresión regular.


![Búsqueda por tarjeta](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ks4tp1653y854k2f8f6j.png)


```java
public void sugerirTarjetas(AjaxBehaviorEvent event) {
  List<Tarjeta> result = new ArrayList<>();
  try {
      textDescripcionToSearch = "";
      findByTarjetas();
      setFirstPageDataTable();
  } catch (Exception e) {          FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
         
    }
}

```

El método sugerirTarjetas se invoca por cada letra que se ingrese a la caja de texto y luego se hace el llamado al método findByTarjetas(). 
Colocaremos un filtro que combina otras condiciones

```java
Bson filter = and(
                eq("active", Boolean.TRUE)
        );
var userView = new UserView(userLogged.getIduser(), userLogged.getName(), userLogged.getPhoto(), userLogged.getEmail());

 Bson filterUser = eq("user.iduser", userView.getIduser());
 for (UserView uv : userViewList) {
   if (userView.getIduser().equals(uv.getIduser())) {
   } else {
filterUser = or(filterUser,eq("user.iduser", uv.getIduser()));
  }
 }
filter = and(filter, filterUser);

paginator = new Paginator.Builder()
           .page(1)
           .filter(filter)
           .sort(sort)
           .sorted(new Sorted(sort))
           .title(filterText)
           .name("findByTarjetas")
           .build();

```
Para realizar la consulta 

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

result = tarjetaServices.searchLikeByTarjeta(textToSearch, paginator.getFilter(), paginator.getSort(), paginator.getPage(), rowPageSmall.get());

```

Recuerde que en la parte 1 definió this.tarjetaLazyDataModel = new LazyDataModel<Tarjeta>(), en el init(), por lo cual se ejecutara el método load() para gestionar los desplazamientos de los documentos en el datatable.