La búsqueda genérica permite a los usuarios buscar en múltiples campos simultáneamente con un único campo de búsqueda. En RAP, esta funcionalidad se controla completamente de forma declarativa a través de anotaciones @Search - sin una línea de JavaScript o código UI5.
El concepto de búsqueda genérica
En las apps Fiori Elements aparece un campo de búsqueda por defecto encima de la tabla. Sin configuración, solo busca en campos explícitamente definidos. Con anotaciones @Search determinas:
- Qué campos se buscan
- Qué tan similar deben ser las coincidencias (Fuzziness)
- Qué tan importante es una coincidencia (Ranking)
┌─────────────────────────────────────────────────┐│ 🔍 [ Munich ] 🔎 │ ← Campo de búsqueda genérico├─────────────────────────────────────────────────┤│ Booking-ID │ Cliente │ Origen │├──────────────┼────────────────┼───────────────┤│ 00001234 │ Hans Müller │ Munich │ ← Coincidencia│ 00005678 │ Anna Schmidt │ Munich │ ← Coincidencia│ 00009012 │ Munich AG │ Frankfurt │ ← Coincidencia (nombre cliente)└─────────────────────────────────────────────────┘Configuración básica: @Search.searchable
La anotación base activa la búsqueda a nivel de View:
@Search.searchable: truedefine view entity ZC_FlightBooking as projection on ZI_FlightBooking{ key BookingId, CustomerName, DepartureCity, ArrivalCity, FlightDate}Importante: @Search.searchable: true a nivel de View es requisito para todas las demás anotaciones de búsqueda.
Definir campos buscables
Con @Search.defaultSearchElement: true marcas campos como buscables:
@Search.searchable: truedefine view entity ZC_FlightBooking as projection on ZI_FlightBooking{ @Search.defaultSearchElement: true key BookingId,
@Search.defaultSearchElement: true CustomerName,
@Search.defaultSearchElement: true DepartureCity,
@Search.defaultSearchElement: true ArrivalCity,
-- Este campo NO se busca FlightDate,
-- Campos técnicos no deberían ser buscables @UI.hidden: true CreatedBy}En este ejemplo, una búsqueda de “Munich” encuentra coincidencias en BookingId, CustomerName, DepartureCity y ArrivalCity - pero no en FlightDate o CreatedBy.
Fuzziness: Búsqueda por similitud
El fuzziness determina qué tan exactamente debe coincidir el término de búsqueda. El valor está entre 0.0 (cualquier coincidencia) y 1.0 (coincidencia exacta).
Valores de Fuzziness explicados
| Valor | Significado | Ejemplo: Búsqueda “Müller” |
|---|---|---|
| 1.0 | Exacto | Solo “Müller” |
| 0.9 | Casi exacto | ”Müller”, “Mueller” |
| 0.8 | Tolerante (Predeterminado) | “Müller”, “Mueller”, “Muller”, “Müler” |
| 0.7 | Muy tolerante | También “Miller”, “Meller” |
Fuzziness en código
@Search.searchable: truedefine view entity ZC_FlightBooking as projection on ZI_FlightBooking{ -- Búsqueda exacta para IDs @Search.defaultSearchElement: true @Search.fuzzinessThreshold: 1.0 key BookingId,
-- Búsqueda tolerante para nombres (errores tipográficos permitidos) @Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.8 CustomerName,
-- Tolerancia media para ciudades @Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.9 DepartureCity,
@Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.9 ArrivalCity}¿Cuándo qué fuzziness?
| Tipo de campo | Fuzziness recomendado | Justificación |
|---|---|---|
| IDs, Códigos | 1.0 | Coincidencia exacta requerida |
| Nombres | 0.7 - 0.8 | Considerar errores tipográficos, acentos |
| Ciudades, Países | 0.85 - 0.9 | Permitir variantes leves |
| Descripciones | 0.7 - 0.8 | Más flexible para texto libre |
| Direcciones email | 1.0 | Exacto |
Ranking: Priorizar resultados de búsqueda
El ranking determina qué coincidencias se muestran primero:
@Search.searchable: truedefine view entity ZC_FlightBooking as projection on ZI_FlightBooking{ -- Máxima prioridad: Número de reserva @Search.defaultSearchElement: true @Search.ranking: #HIGH key BookingId,
-- Prioridad media: Nombre de cliente @Search.defaultSearchElement: true @Search.ranking: #MEDIUM CustomerName,
-- Baja prioridad: Ciudades @Search.defaultSearchElement: true @Search.ranking: #LOW DepartureCity,
@Search.defaultSearchElement: true @Search.ranking: #LOW ArrivalCity}Niveles de Ranking
| Nivel | Uso |
|---|---|
#HIGH | Identificadores primarios (IDs, números) |
#MEDIUM | Campos de negocio importantes (nombres, designaciones) |
#LOW | Información secundaria (descripciones, comentarios) |
Si el usuario busca “00001234”, las coincidencias en BookingId aparecen antes que las de CustomerName.
Ejemplo completo de reserva de vuelos
Aquí una CDS View completamente anotada para búsqueda de reservas de vuelos:
@EndUserText.label: 'Reserva de vuelo - Projection'@AccessControl.authorizationCheck: #CHECK@Metadata.allowExtensions: true
@Search.searchable: truedefine view entity ZC_FlightBooking as projection on ZI_FlightBooking{ -- Clave primaria con ranking alto @Search.defaultSearchElement: true @Search.fuzzinessThreshold: 1.0 @Search.ranking: #HIGH @UI.lineItem: [{ position: 10 }] key BookingId,
-- Datos de vuelo con ranking medio @Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.9 @Search.ranking: #MEDIUM @UI.lineItem: [{ position: 20 }] CarrierId,
@Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.9 @Search.ranking: #MEDIUM @UI.lineItem: [{ position: 30 }] ConnectionId,
-- Datos de cliente con alto fuzziness para errores tipográficos @Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.8 @Search.ranking: #MEDIUM @UI.lineItem: [{ position: 40 }] CustomerName,
-- Ubicaciones buscables @Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.85 @Search.ranking: #LOW @UI.lineItem: [{ position: 50 }] DepartureCity,
@Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.85 @Search.ranking: #LOW @UI.lineItem: [{ position: 60 }] ArrivalCity,
-- Fecha NO buscable (usar filtros separados) @UI.lineItem: [{ position: 70 }] @UI.selectionField: [{ position: 10 }] FlightDate,
-- Estado con Value Help, no buscable @UI.lineItem: [{ position: 80 }] @UI.selectionField: [{ position: 20 }] BookingStatus,
-- Monto no buscable @Semantics.amount.currencyCode: 'CurrencyCode' @UI.lineItem: [{ position: 90 }] FlightPrice,
@Semantics.currencyCode: true CurrencyCode,
-- Campos administrativos ocultos y no buscables @UI.hidden: true CreatedBy,
@UI.hidden: true CreatedAt,
@UI.hidden: true LastChangedBy,
@UI.hidden: true LastChangedAt}Mejores prácticas para campos buscables
Campos que deberían ser buscables
- Claves primarias: BookingId, OrderId, CustomerNumber
- Nombres: CustomerName, ProductName, Description
- Códigos con significado: CarrierId, MaterialGroup
- Ubicaciones: City, Country, Region
Campos que NO deberían ser buscables
- Campos de fecha: Usar campos de filtro separados
- Valores numéricos: Montos, cantidades vía filtros
- Campos técnicos: GUIDs, Timestamps
- Campos administrativos: CreatedBy, ChangedAt
- Campos binarios: Flags, Status (mejor: Filtro con Value Help)
Ejemplo: Diseño bueno vs. malo
-- ❌ MALO: Todo buscable@Search.searchable: truedefine view entity ZC_Order { @Search.defaultSearchElement: true key OrderGuid, -- ¿GUID buscable?
@Search.defaultSearchElement: true OrderDate, -- ¿Fecha buscable?
@Search.defaultSearchElement: true TotalAmount, -- ¿Monto buscable?
@Search.defaultSearchElement: true CreatedAt -- ¿Timestamp buscable?}
-- ✅ BUENO: Selección dirigida@Search.searchable: truedefine view entity ZC_Order { @Search.defaultSearchElement: true @Search.ranking: #HIGH @Search.fuzzinessThreshold: 1.0 key OrderId, -- Número de pedido buscable
@Search.defaultSearchElement: true @Search.ranking: #MEDIUM @Search.fuzzinessThreshold: 0.8 CustomerName, -- Nombre de cliente buscable
@UI.selectionField: [{ position: 10 }] OrderDate, -- Fecha como filtro
@Semantics.amount.currencyCode: 'Currency' TotalAmount, -- Monto no buscable
@UI.hidden: true CreatedAt -- Oculto}Consideraciones de rendimiento
Indexación
Los campos buscables deberían estar indexados en la base de datos:
-- En la definición de tabla@AbapCatalog.tableCategory: #TRANSPARENTdefine table zflight_book { key client : abap.clnt not null; key booking_id : abap.numc(10) not null;
-- Índice en campos frecuentemente buscados customer_name : abap.char(80); departure_city : abap.char(40); arrival_city : abap.char(40);}Limitar cantidad de campos buscables
-- ❌ Demasiados campos buscables (problema de rendimiento)-- 15+ campos con @Search.defaultSearchElement: true
-- ✅ Selección enfocada (5-8 campos)@Search.defaultSearchElement: trueBookingId,
@Search.defaultSearchElement: trueCustomerName,
@Search.defaultSearchElement: trueDepartureCity,
@Search.defaultSearchElement: trueArrivalCity,
@Search.defaultSearchElement: trueCarrierIdGrandes volúmenes de datos
Para grandes volúmenes de datos se recomienda:
@ObjectModel.resultSet.sizeCategory: #XS -- < 100 entradas@ObjectModel.resultSet.sizeCategory: #S -- < 1.000 entradas@ObjectModel.resultSet.sizeCategory: #M -- < 10.000 entradas@ObjectModel.resultSet.sizeCategory: #L -- > 10.000 entradasPara grandes volúmenes de datos, desactivar búsqueda automática al escribir y forzar búsqueda explícita.
Resumen de anotaciones Search
| Anotación | Valores | Descripción |
|---|---|---|
@Search.searchable | true/false | Activa búsqueda a nivel de View |
@Search.defaultSearchElement | true/false | Campo es buscable |
@Search.fuzzinessThreshold | 0.0 - 1.0 | Umbral de similitud |
@Search.ranking | #HIGH, #MEDIUM, #LOW | Prioridad en resultados |
Combinación con filtros
La búsqueda genérica complementa, pero no reemplaza los filtros:
@Search.searchable: truedefine view entity ZC_FlightBooking{ -- Buscable Y como filtro @Search.defaultSearchElement: true @Search.ranking: #HIGH @UI.selectionField: [{ position: 5 }] key BookingId,
-- Solo buscable (no necesita filtro explícito) @Search.defaultSearchElement: true CustomerName,
-- Solo como filtro (no buscable) @UI.selectionField: [{ position: 10 }] FlightDate,
-- Solo como filtro con Value Help @UI.selectionField: [{ position: 20 }] @Consumption.valueHelpDefinition: [{ entity: { name: 'ZI_BookingStatusVH' } }] BookingStatus}Conclusión
La búsqueda genérica en RAP ofrece una forma poderosa y declarativa para funciones de búsqueda amigables:
| Aspecto | Recomendación |
|---|---|
| Activación | @Search.searchable: true en View |
| Campos | 5-8 campos de negocio relevantes |
| Fuzziness | 1.0 para IDs, 0.8 para nombres |
| Ranking | #HIGH para claves primarias |
| Rendimiento | Índices, cantidad limitada de campos |
Con pocas anotaciones logras una función de búsqueda profesional que permite a los usuarios encontrar datos rápidamente.
Artículos relacionados
- Fundamentos de RAP - Introducción a RESTful ABAP Programming
- Anotaciones CDS - Todas las anotaciones en detalle
- RAP Value Helps - Ayudas de valores para campos de filtro
- RAP CDS Pattern - Arquitectura RAP simplificada