2012-04-30 6 views
5

Tengo millones de artículos ordenados por una puntuación precalculada. Cada elemento tiene muchos atributos booleanos. Let dice que hay unos diez mil atributos posibles en total, cada elemento tiene una docena de ellos.Solución de Datastore para la búsqueda de etiquetas

Me gustaría poder solicitar en tiempo real (unos milisegundos) los n primeros elementos dados ~ cualquier combinación de atributos.

¿Qué solución recomendarías? Estoy buscando algo extremadamente escalable.

-
- Actualmente estamos buscando en mongodb y la matriz de índice, lo que ves ningún tipo de limitación?
- SolR es una posible solución, pero no necesitamos capacidades de búsqueda de texto.

+1

cuando dice "ordenado por puntaje" ¿quiere decir que esto ya está precalculado? Si es así, entonces SOLR puede no proporcionar ningún beneficio. De lo contrario, SOLR proporciona una clasificación de relevancia muy potente y personalizable. – nickdos

+0

Millones de artículos no son un problema para SOLR, pero 10.000 posibles atributos _ podrían ser un problema. SOLR admite campos dinámicos para que no tenga que definir todos los atributos, pero la memoria podría explotar con un esquema ancho/disperso. Otros pueden aconsejar sobre esto mejor. – nickdos

+0

@nickdos sí, el puntaje está precalculado. Y creo que tienes razón, la parte difícil es la gran cantidad de atributos. No sé cómo mongodb manejar esto. ¿Crea un índice por atributos? ¿Es posible tener tantos índices? Vamos a probar de todos modos, pero me gustaría estar seguro de que no perdemos la estrategia correcta. – log0

Respuesta

9

MongoDB puede manejar lo que quiere, si se almacenan los objetos como éste

{ score:2131, attributes: ["attr1", "attr2", "attr3"], ... } 

A continuación, la siguiente consulta coincidirá con todos los elementos que tienen ATT1 y attr2

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr2" ] } }) 

pero esto won' t hacer que coincida

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr4" ] } }) 

la consulta devuelve un cursor, si desea que se ordene este cursor, t gallina sólo tiene que añadir los parámetros de clasificación de la consulta como tal

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr2" ] }}).sort({score:1}) 

Tenga una mirada en Advanced Queries para ver lo que es posible.

índices apropiados pueden ser configurados de la siguiente manera

db.mycol.ensureIndex({attributes:1, score:1}) 

Y se puede obtener información sobre el rendimiento utilizando

db.mycol.find({ attributes: { $all: [ "attr1" ] }}).explain() 

Mongo explica cómo se escanearon muchos objetos, el tiempo que la operación se llevó a y varias otras estadísticas .

+0

De hecho, mongodb parece ajustarse muy bien a la necesidad, pero me preocupa la eficiencia. No mencionaste los índices aquí. Es un índice de atributos y puntajes suficiente en mi caso ... – log0

+0

He agregado información sobre los índices. Asegúrese de que todos sus índices quepan en la memoria, de lo contrario, sus consultas se volverán lentas. –

+0

Leí en alguna parte que podría haber un máximo de 64 índices en una colección. ¿Qué sucede en caso de matriz indexada? ¿Significa que mongo creará 10 000 índices? – log0

2

Esto es exactamente lo que Mongo puede manejar. El hecho de que tus atributos sean de tipo booleano ayuda aquí. Un posible esquema se enumeran a continuación:

[ 
    { 
     true_tags:[attr1, attr2, attr3, ...], 
     false_tags: [attr4, attr5, attr6, ...] 
    }, 
] 

entonces podemos índice en true_tags y false_tags. Y debería ser eficiente buscar con $ in, $ all, ... operadores de consulta.

+0

Lo siento, no fue muy claro, pero por booleano me refiero a que o bien el elemento tiene el atributo no. Su respuesta sigue en pie, pero estoy buscando información más precisa. ¿Hay alguna limitación en ese tipo de índice (parece que existe el tamaño de la clave, el número máximo de índice, etc. pero tal vez mi información es antigua)? ¿Cómo funciona con sharding? – log0

2

Redis sería un candidato perfecto para

  • "los mejores n elementos" para "millones de artículos ordenados por puntuación de"

Redis ha construido en la estructura de datos que pueda comenzar desde: Sorted Set => cada miembro de un conjunto ordenado está asociado con la puntuación. Que por ejemplo puede ser clasificada por un resultado con ZRANGEBYSCORE:

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 

os animo a mirar Ordenado Conjunto commands y tener una idea de Redis, como su problema (como se dice) lo solicite. Por supuesto, puede mantener tantos atributos como desee dentro de un único elemento de Conjunto.


En lo que MongoDB, ya que ha mencionado millones, a menos que pueda doblarse consultas incrementales a trabajar para su problema, lo que no esperar una respuesta de segundo sub.

Como @nickdos mencionó Solr La relevancia es una característica bastante poderosa, pero el número de atributos será, ya que tendría que mantener todos estos atributos en memoria para cada elemento. Aunque una docena para cada uno puede no ser tan malo => solo intenta ver.

Cuestiones relacionadas