Ir al contenido principal

Concordancia

Una concordancia responde a «¿dónde aparece esta palabra, en todas partes, en orden?». Es una pregunta distinta a la de una búsqueda, y concordance está hecha para responderla exactamente:

  • Exhaustiva — todas las apariciones, accesibles mediante paginación. No se descarta nada.
  • En orden canónico — Génesis → Apocalipsis, luego capítulo, luego versículo. Nunca ordenada por relevancia.
  • Agregada — los totales por libro y por testamento llegan junto a la página.
  • Con contexto — cada aparición incluye un fragmento de palabra clave en contexto.
Requiere un índice

Las queries de concordancia necesitan que la traducción esté indexada. Revisa concordanceIndexedAt en la traducción — si es null, la query devuelve un error indicando qué tarea rake ejecutar. Consulta Traducciones.

Una query completa​

query ConcordanceBasic {
concordance(translation: "spa-rv1909", word: "misericordia", first: 10) {
totalCount
entry {
lemma
surfaceForms
totalOccurrences
verseCount
occurrencesByTestament {
old
new
}
}
edges {
cursor
node {
verse {
bookName
chapter
verse
text
}
context
}
}
pageInfo {
hasNextPage
endCursor
}
}
}

Leer la respuesta​

Tres partes, cada una responde algo distinto.

entry — agregados de toda la traducción​

entry {
lemma
surfaceForms
totalOccurrences
verseCount
occurrencesByBook { bookId bookName count }
occurrencesByTestament { old new }
}

Estos cubren toda la traducción y no se ven afectados por la paginación. Tampoco los afectan tus filtros book y testament: entry siempre describe la palabra de forma global, que es justo lo que lo hace útil como encabezado sobre unos resultados filtrados.

  • lemma es la raíz normalizada, y puede verse extraña (misericordi). Es una clave de índice, no algo para mostrar al usuario.
  • surfaceForms es lo que se muestra: hasta 10 formas reales encontradas en el texto, de más a menos frecuente. Es una muestra, no una lista exhaustiva.
  • totalOccurrences cuenta tokens; verseCount cuenta versículos. El primero puede superar al segundo cuando una palabra se repite dentro de un mismo versículo.

edges — esta página de apariciones​

edges {
cursor
node {
context
verse { bookName chapter verse text }
}
}
context contiene HTML

context envuelve el término coincidente en etiquetas <mark>. Se genera en el servidor a partir del texto del versículo, pero aun así debes sanearlo antes de renderizarlo como HTML; nunca lo insertes en el DOM sin escapar por costumbre.

pageInfo — dónde estás​

pageInfo { hasNextPage endCursor }

Paginación​

Pasa endCursor de vuelta como after:

query {
concordance(translation: "spa-rv1909", word: "amor", first: 25, after: "UFNBOjIzOjE=") {
edges { cursor node { verse { bookName chapter verse } } }
pageInfo { hasNextPage endCursor }
}
}

Los cursores son opacos: no los decodifiques ni los construyas. first es 25 por defecto y se limita al rango 1–100.

Sigue paginando mientras hasNextPage sea verdadero. Como el orden es canónico y estable, un cursor sigue siendo válido entre peticiones mientras la traducción no se haya reindexado.

Filtros​

ArgumentoEfecto
bookId canónico (PSA) o nombre localizado (Salmos)
testamentOLD o NEW

Los dos se combinan con AND — book: "PSA", testament: OLD es un filtro válido y no contradictorio. Esto difiere de randomVerse, donde books anula testament; consulta Comportamiento de la API.

query ConcordanceByBook {
concordance(
translation: "spa-rv1909"
word: "misericordia"
book: "Salmos"
first: 10
) {
totalCount
edges {
node {
verse {
bookName
chapter
verse
text
}
}
}
}
}

Fíjate en dos cosas de esa respuesta. totalCount baja de 398 a 164: el total solo de Salmos. Y book aceptó "Salmos", el nombre localizado, en lugar del canónico PSA; ambos funcionan.

Los filtros restringen edges y totalCount, pero no entry, que sigue siendo de toda la traducción. Eso es intencional: permite mostrar «164 de 398 apariciones están en Salmos» con una sola petición.

Stemming​

La coincidencia pasa por el diccionario de búsqueda de texto de PostgreSQL de la traducción, así que amor encuentra amores y amoroso. Que eso ocurra depende de la traducción:

  • hasStemming: true — hay stemming lingüístico disponible para ese idioma
  • hasStemming: false — solo coinciden las formas exactas

Revísalo antes de prometer a los usuarios coincidencia flexible de palabras.

Presupuesto de complejidad​

concordance tiene un coste de complejidad proporcional a first, frente al presupuesto global del esquema de 300. Pedir first: 100 junto con selecciones muy anidadas de verse puede superarlo. Si te topas con un error de complejidad, reduce first o selecciona menos campos por aparición.

El índice de palabras​

Para explorar qué palabras existen en lugar de buscar una, usa concordanceIndex:

query {
concordanceIndex(translation: "spa-rv1909", prefix: "mis", first: 5) {
lemma
verseCount
totalOccurrences
}
}

Devuelve una lista alfabética de frecuencias, útil para construir una página de estudio de palabras o un autocompletado. minOccurrences descarta palabras raras; first se limita al rango 1–200.

Ten en cuenta que estas entradas son valores de lemma, con la misma salvedad de antes: son raíces, no formas para mostrar.