Tenemos un problema con nuestra estructura de datos en SQL Server ya que estamos ordenando por un campo calculado. Con esto en mente, nos preguntábamos si sería posible usar map reduce para preparar índices para mantener nuestras respuestas ágiles, específicamente dentro de RavenDB.

Para su información, pregunté esto anteriormente en DBA y obtuve excelentes respuestas, pero quería considerar este enfoque diferente:

Intentaré dar un ejemplo, esta no es la estructura de mi tabla, simplemente estoy tratando de delinear el problema para encontrar una solución ...

Identificación de la persona, nombre

BrothersNames Id, nombre

SistersNames Id, nombre

PersonBrothers (unirse a la tabla) PersonId, BrotherNameId

PersonSisters (unirse a la tabla) PersonId, SisterNameId

Bien, imagina que esta base de datos contiene a todas las personas de un país pequeño. La base de datos contiene un registro de los nombres de los hermanos y hermanas de todos (no asigna a una persona a su hermano o hermana, solo sus nombres) para que podamos encontrar estadísticas sobre los nombres.

Obviamente, se comparten muchos nombres, por lo que actualmente en SQL Server las tablas de combinación normalizan esto para nosotros.

Lo que quiero hacer es tomar un usuario y averiguar la cantidad de coincidencias de los nombres de los hermanos y la cantidad de coincidencias de los nombres de las hermanas con todos los demás usuarios del sistema, luego agregar esas dos coincidencias y ordenarlas de forma descendente. Así que esto nos daría una lista de usuarios que tienen la mayor cantidad de nombres de hermanos y hermanas en común.

Realmente solo estoy interesado en los diez primeros partidos, pero creo que tengo que obtener el conjunto de resultados completo para trabajar en los diez primeros partidos.

Tenga en cuenta que, en mis datos reales, una persona puede tener un millón de hermanos o un millón de hermanas. Aquí es donde tengo problemas de rendimiento.

Así es como estoy calculando las coincidencias para los hermanos y hago lo mismo para las hermanas.

select p.id, matches
FROM Person p
LEFT JOIN 
    (
        SELECT 
        COUNT(*) AS Matches,
        pbn.PersonId
        FROM PersonBrothersNames pbn
        INNER JOIN Brothersnames bn on pbn.BrothernameId =bn.Id
        inner join PersonBrothersName otherpbn on otherpbn.BrothernameId = bn.Id

        WHERE pbn.PersonId= @PersonId and pbn.PersonId <> otherpbn.personid
        GROUP BY  pbn.PersonId

    ) As BrothersNamesJoin ON BrothersNamesJoin.Person = p.Id
2
Victoria 9 feb. 2012 a las 14:05

1 respuesta

La mejor respuesta

Lo que puedes hacer es algo como esto:

     { "Name": "a", "Brothers": ["b","c"] }

Luego, puede indexarlos y usar el paquete Más como este para buscar a otras personas con nombres de hermanos similares. Y sí, los clasificará por usted.

2
Ayende Rahien 9 feb. 2012 a las 15:43
Si una persona puede tener 1,5 millones de hermanos (sé que eso es imposible en la vida real), ¿esto seguirá respondiendo rápidamente con un índice de Más como este?
 – 
Victoria
9 feb. 2012 a las 19:06
Sí, porque no maneja esto de la misma manera. Realiza comparaciones sobre vectores de similitudes.
 – 
Ayende Rahien
9 feb. 2012 a las 20:14
Como siempre, tienes que probar. No lo he probado con 1,5 mil, pero se probó con grandes cantidades de datos
 – 
Ayende Rahien
9 feb. 2012 a las 20:15
Gracias Ayende - probaré y comentaré aquí más tarde
 – 
Victoria
9 feb. 2012 a las 20:47
Hemos intentado guardar un documento con entradas de 1,5 mil como se indica en su respuesta (cada una es larga) y la aplicación Silverlight no responde. ¿Esto se debe a que Raven no puede administrar documentos tan grandes o es una limitación del cliente Silverlight? Intentaremos consultar directamente ...
 – 
Victoria
9 feb. 2012 a las 21:10