Tengo problemas para obtener la traducción correcta/mejor para 'hola' del inglés al francés. Después de un poco de depuración, descubrí que los primeros tres (3) documentos devueltos por mi agregación tienen la misma puntuación de '2.362138271331787' cada uno.
Espero que 'hola' tenga una puntuación más alta, ya que tiene una coincidencia exacta con la misma consulta de búsqueda, pero 'es suyo' y 'suyo' parece tener la misma puntuación que 'hola'.
Aquí está mi consulta de búsqueda:
const searchOption= [ { $search: { text: { query: 'hi', path: 'english', }, }, }, { $project: { _id: 0, french: 1, english: 1, score: { $meta: "searchScore" } } }, { $limit: 5 }, ]; const result = await Greetings.aggregate(searchOption, { cursor: { batchSize: 5 } }).toArray();Aquí están los documentos devueltos. La lista está ordenada por puntuación de búsqueda:
[ { "english": "it's his", "french": "c'est le sien", "score": 2.362138271331787 }, { "english": "hi", "french": "salut", "score": 2.362138271331787 }, { "english": "his", "french": "le sien", "score": 2.362138271331787 }, { "english": "it's his failure to arrange his", "french": "c'est son incapacité à organiser son", "score": 2.2482824325561523 }, { "english": "it's his failure to arrange his time", "french": "c'est son incapacité à organiser son temps", "score": 2.0995540618896484 } ]Esta es una limitación conocida de Atlas Search y la solución se menciona aquí: https://www.mongodb.com/docs/atlas/atlas-search/autocomplete/#limitations
El analizador lucene.keyword en un tipo de string es muy útil para coincidencias exactas en escenarios donde la fidelidad de la puntuación es esencial.
Básicamente, la ruta en inglés debe definirse en la definición del índice como autocompletar y cadena, como:
[ {"type": "string"}, {"type": "autocomplete"} ]Lo anterior supone que no está utilizando un analizador de idioma para autocompletar o cadenas, lo que probablemente no sea ideal para cadenas.
Luego, en el lado de la consulta, desea una consulta compound donde ambas opciones sean cláusulas should Debe impulsar la cláusula de text y no la cláusula de autocompletar.
El puntaje es un "puntaje de relevancia" implementado internamente por Mongo, diré que me sorprende que la longitud del campo no sea parte del puntaje, incluso si es un operando de "texto", personalmente esperaría que se agregue de alguna forma en el futuro cercano.
Por ahora, podría usar una solución alternativa para construir la partitura que desea, por ejemplo, podría usar expresiones should (o) con un operador de phrase combinado con una función de puntuación mejorada, así:
const searchOption= [ { $search: { "compound": { "should" : [ { "phrase":{ "query": "hi", "path": "english", "score": {"boost":{"value":5}} } }, { text: { query: 'hi', path: 'english', }, }, ] } } }, { $project: { _id: 0, french: 1, english: 1, score: { $meta: "searchScore" } } }, { $limit: 5 }, ]; const result = await Greetings.aggregate(searchOption, { cursor: { batchSize: 5 } }).toArray(); De lo contrario, también podría simplemente ordenar por longitud en english combinada con el puntaje (esto es bajo el supuesto de que los puntajes estarán empatados), obviamente, esto no es un ordenamiento real, ya que asume que los 5 mejores resultados son los 5 mejores resultados reales que espera. obtener.
const searchOption= [ { $search: { text: { query: 'hi', path: 'english', }, }, }, { $project: { _id: 0, french: 1, english: 1, score: { $meta: "searchScore" }, len: {$strLenCP: "$english"} } }, { $sort : { score: -1, len: -1 } }, { $limit: 5 }, ]; const result = await Greetings.aggregate(searchOption, { cursor: { batchSize: 5 } }).toArray();