2011-11-22 13 views
9

Supongamos que tengo una colección de usuarios y deseo implementar la autocompletar en los nombres de usuario de esos usuarios. Miré los documentos de mongodb y $ regex parece ser una forma de hacer esto. ¿Hay una mejor manera? Por mejor me refiero a una mejor actuación/mejor práctica.Implementar autocompletar en MongoDB

Respuesta

9

Según lo sugerido por @Thilo, puede usar varias ideas, incluido el prefijo.

Lo más importante es tener una solicitud muy rápida (porque desea autocompletar a sentir instaneous). Por lo tanto, debe usar la consulta que utilizará los índices correctamente.

Con regexp: use /^prefix/ (lo importante es^para especificar el comienzo de la línea que es obligatorio para que la consulta utilice el índice).

La consulta rango es bueno también: { $gt : 'jhc', $lt: 'jhd' } }

más complicado, pero más rápido: se puede almacenar-prefijo árboles en mongo (aka intentos) con entradas como:

{usrPrefix : "anna", compl : ["annaconda", "annabelle", "annather"]} 
{usrPrefix : "ann", compl : ["anne", "annaconda", "annabelle", "annather"]} 

Esta última solución es muy rápida (si los índices en compl, por supuesto) pero no espacio eficiente en absoluto. Usted conoce la compensación que también ha elegido.

+0

Excelente respuesta. No había pensado en completar con tries. Personalmente, nunca tuve una sensación 'instantánea' al usar Regexes en Mongo. ¡Esto debería hacer el truco para hacerlo mucho más rápido! – Vivek

+0

De hecho, expresiones regulares en mongo no están realmente bien implementadas. Sin embargo, cuando quieres algo fluido, no piensas consultar la base de datos en vivo, la latencia es simplemente demasiado alta. Una forma adecuada de implementar la finalización automática sería cargar asincrónicamente algunas terminaciones habituales y completarlas a medida que transcurra el tiempo (y la entrada del usuario). – kamaradclimber

2

Si usted está buscando para los prefijos, se puede utilizar una consulta de gama (no estoy seguro acerca de la sintaxis exacta):

db.users.find({'username': { $gt : 'jhc', $lt: 'jhd' } }) 

y desea que un índice en el campo de nombre de usuario.

+0

¿Podría explicarnos cómo funciona la consulta de rango en este ejemplo? por ejemplo, si tengo "gatos" en mi colección, ¿cómo devolvería "ca" el término correcto? – wazzaday

+0

Puede buscar todo entre "ca" y "cb". 'ca Thilo

5

lo hacemos utilizando expresiones regulares y es rápido, siempre y cuando usted tiene un índice y utiliza/^/valor

Tenga en cuenta que no puede utilizar el caso opción insensible con un índice, por lo que es posible que desee almacene una versión en minúscula de su cadena como otro campo en su documento y úselo para la autocompletar.

He realizado pruebas con más de 3 millones de documentos y aún parece instantáneo.