sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB:Cómo hacer una búsqueda de texto y ordenar por fecha

Independientemente de otras claves de índice compuesto, debe incluir el $meta para el "textScore" para obtener la clasificación correcta:

db.collection.find(
    { "$text": { "$search": "\"[email protected]\""}},
    { "score": { "$meta": "textScore" } }
).sort({
    "score": { "$meta": "textScore" }, "Date": 1
})

Entonces, naturalmente, desea que esa "puntuación" se ordene primero y luego por "Fecha" para que las cosas se clasifiquen correctamente según la relevancia de la búsqueda.

El orden del índice no importa, pero, por supuesto, solo puede tener un índice de texto "uno". Así que asegúrese de eliminar todos los demás antes de crear:

db.collection.createIndex({ 
   "From": "text",
   "To": "text",
   "CC":"text", 
   "BCC": "text", 
   "Date":1
})

Busque índices que estén actualizados con:

db.collection.getIndicies()

O simplemente déjalo todo y comienza de nuevo:

db.collection.dropIndexes()

Sin embargo, para los datos que parece estar buscando, habría pensado que un índice compuesto regular en cada campo debería ser más adecuado para usted. La búsqueda de direcciones de "correo electrónico" debe ser una "coincidencia exacta", y si espera varios elementos para cada campo, deben ser conjuntos de cadenas, así:

{
    "TO": ["[email protected]"],
    "FROM": ["[email protected]"],
    "CC": ["[email protected]","[email protected]"],
    "BCC": [],
    "Date": ISODate("2015-07-27T13:42:05.535Z")
}

Luego, necesita índices separados en cada campo, posiblemente en combinación con "Fecha", así:

db.email.createIndex({ "TO": 1, "Date": 1 })
db.email.createIndex({ "FROM": 1, "Date": 1 })
db.email.createIndex({ "CC": 1, "Date": 1 })
db.email.createIndex({ "BCC": 1, "Date": 1 })

Y consulta con un $or condición:

db.email.find({
    "$or": [
        { "TO": "[email protected]" },
        { "FROM": "[email protected]" },
        { "CC": "[email protected]" },
        { "BCC": "[email protected]" }
    ],
    "Date": { "$lt": new Date() }
})

Si observa el .explain(true) (detallado) resultado de eso, debería ver que el plan ganador es una "intersección de índice" de todos los índices especificados. Esto resulta ser muy eficiente ya que cada campo (e índice seleccionado) tiene un valor de coincidencia exacta y una coincidencia de rango en la fecha indexada.

Eso será mucho mejor para usted que la "coincidencia aproximada" de las búsquedas de texto. Incluso las expresiones regulares deberían funcionar mejor aquí en general (para direcciones de correo electrónico) y especialmente si están "ancladas" ^ al comienzo de la cadena.

Los índices de texto están destinados a que coincidan "palabras como tokens", pero estos no deberían ser sus datos. El $or no se ve bien, pero debería funcionar mucho mejor.