moreLikeThis Limitaciones del operador
No se puede usar el operador moreLikeThis para consultar valores que no sean cadenas. Para buscar valores que no sean cadenas, se puede combinar una consulta moreLikeThis con una cerca, rango o cualquier otro operador en una consulta compuesta.
No se puede utilizar el moreLikeThis operador dentro del embeddedDocument para consultar documentos en una matriz.
Definición
Comportamiento
Cuando ejecuta una consulta moreLikeThis, MongoDB Search realiza estas acciones:
Extrae un número limitado de términos más representativos en función de los documentos de entrada que especifique en la opción
likedel operador.Crea una consulta de disyunción(OR) para encontrar documentos similares según los términos más representativos y devuelve los resultados.
El moreLikeThis operador busca documentos similares utilizando el analizador especificado en la configuración del índice. Si omite el analizador en la definición del índice, el moreLikeThis operador utiliza el analizador estándar predeterminado. Si especifica varios analizadores, el moreLikeThis operador ejecuta el texto de entrada en cada analizador, busca y devuelve resultados para todos.
Para ver la disyunción (OR) que MongoDB Searchconstruye para encontrar documentos similares, utilice explain con su moreLikeThis consulta del operador.
Uso
Antes de ejecutar la consulta del operador moreLikeThis, le recomendamos recuperar uno o más documentos de entrada. Para ello, puede realizar una de las siguientes acciones:
Ejecute una consulta, como por ejemplo find(), u otra consulta MQL para encontrar DocumentosBSON.
Ejecute cualquier canal de agregación que devuelva documentos BSON.
Utilice cualquier otra fuente de documentos en su solicitud.
Una vez que identifique los documentos de entrada, puede pasarlos al operador moreLikeThis.
Al ejecutar una moreLikeThis consulta con el operador, MongoDB Search devuelve el documento de entrada original en los resultados de la consulta. Para omitir el documento de entrada, utilice el moreLikeThis operador en una consulta con operador compuesto y excluya el documento de entrada _id por equals su valor mediante el operador en la cláusula mustNot.
Sintaxis
moreLikeThis tiene la siguiente sintaxis:
{ "$search": { "index": index name, // optional, defaults to "default" "moreLikeThis": { "like": [ { <"field-name">: <"field-value">, ... }, ... ], "score": <options> } } }
opciones
moreLikeThis utiliza la siguiente opción para construir una consulta:
Campo | Tipo | Descripción | Necesidad |
|---|---|---|---|
| un documento BSON o un arreglo de documentos | Uno o más documentos BSON que MongoDB Search utiliza para extraer términos representativos para consultas. | Requerido |
| Objeto | Puntuación para asignar a los resultados de búsqueda coincidentes. Puede modificar la puntuación predeterminada con las siguientes opciones:
Para obtener información sobre el uso de Al consultar valores de una matriz, MongoDB Search asigna puntuaciones más altas si más valores en la matriz coinciden con la consulta. | Opcional |
Ejemplos
Los ejemplos utilizan la colección movies en la base de datos sample_mflix. Cada ejemplo de esta sección utiliza una definición de índice diferente para demostrar las distintas características del operador.
Antes de ejecutar las consultas de ejemplo en el clúster, cargue los datos de muestra y cree el índice sugerido. Para obtener más información sobre cómo crear un índice de búsqueda de MongoDB mediante la interfaz de usuario, la API o la CLI,consulte Administrar índices de búsqueda de MongoDB. Las definiciones de índice usan el default nombre.
Si se nombra el índice default, no se necesita especificar un parámetro index en la etapa de la $search pipeline. Si se asigna un nombre personalizado al índice, se debe especificar este nombre en el parámetro index.
Ejemplo 1: Documento único con múltiples campos
El siguiente ejemplo utiliza el moreLikeThis operador para buscar documentos similares a varios valores de campo. En este ejemplo, la definición de índice contiene asignaciones dinámicas para indexar dinámicamente todos los tipos de campo indexables dinámicamente en la colección. La definición de índice para la sample_mflix.movies colección debería ser similar a la siguiente.
{ "mappings": { "dynamic": true } }
Ejemplo
La siguiente consulta busca películas similares al título de entrada "El Padrino" y al género de entrada "acción". Incluye una etapa para limitar la salida $limit a 5 resultados y una etapa para excluir todos los campos $project excepto,title released genresy.
1 db.movies.aggregate([ 2 { 3 "$search": { 4 moreLikeThis: { 5 like: 6 { 7 "title": "The Godfather", 8 "genres": "action" 9 } 10 } 11 } 12 }, 13 { "$limit": 5}, 14 { 15 $project: { 16 "_id": 0, 17 "title": 1, 18 "released": 1, 19 "genres": 1 20 } 21 } 22 ])
[ { genres: [ 'Comedy', 'Drama', 'Romance' ], title: 'Godfather' }, { genres: [ 'Crime', 'Drama' ], title: 'The Godfather', released: ISODate("1972-03-24T00:00:00.000Z") }, { genres: [ 'Crime', 'Drama' ], title: 'The Godfather: Part II', released: ISODate("1974-12-20T00:00:00.000Z") }, { genres: [ 'Crime', 'Drama' ], title: 'The Godfather: Part III', released: ISODate("1990-12-26T00:00:00.000Z") }, { genres: [ 'Action' ], title: 'The Defender', released: ISODate("1994-07-28T00:00:00.000Z") } ]
Los resultados de búsqueda de MongoDB contienen películas similares al título de la película de entrada "El Padrino" y al género de la película de entrada "acción".
Ejemplo 2: Documento de entrada excluido en los resultados
El siguiente ejemplo utiliza find() para identificar un documento de entrada y luego utiliza el operador moreLikeThis para buscar documentos similares. Para este ejemplo, la definición del índice utiliza mapeos estáticos para indexar únicamente los campos title, genres y _id.
1 { 2 "mappings": { 3 "dynamic": false, 4 "fields": { 5 "title": { 6 "type": "string" 7 }, 8 "genres": { 9 "type": "string" 10 }, 11 "_id": { 12 "type": "objectId" 13 } 14 } 15 } 16 }
Ejemplo
La siguiente consulta find() busca la película titulada "El Padrino" y almacena el resultado en movie. Especifica que los resultados solo deben contener los campos title y genres de los documentos coincidentes. Tenga en cuenta que, por defecto, el comando find
() siempre devuelve el campo _id, cuyo valor podría variar en su clúster.
movie = db.movies.find( { title: "The Godfather" }, { genres: 1, title: 1} ).toArray()
[ { _id: ObjectId("573a1396f29313caabce4a9a"), genres: [ 'Crime', 'Drama' ], title: 'The Godfather' } ]
La siguiente consulta utiliza un operador compuesto con el operador moreLikeThis para consultar los campos title y genres, y el operador equals para excluir el documento de entrada utilizando las siguientes cláusulas:
La cláusula
mustpara consultar películas similares a la película almacenada enmovie.La cláusula
mustNotexcluye el documento de entrada de los resultados por su valor_id. Tenga en cuenta que el valor_idutilizado en la consulta coincide con el valor_idde los resultados de la consultafind()anterior.
La consulta limita la salida a 5 resultados. Utiliza una etapa para incluir $project los _id titlecampos,, released y genres en los resultados.
Nota
Antes de ejecutar esta consulta, reemplaza el valor del campo _id de la línea 13 por el valor del campo _id en tus resultados de consulta.
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "compound":{ 5 "must":[{ 6 "moreLikeThis": { 7 "like": movie 8 } 9 }], 10 "mustNot":[{ 11 "equals": { 12 "path": "_id", 13 "value": ObjectId ("573a1396f29313caabce4a9a") 14 } 15 }] 16 } 17 } 18 }, 19 {"$limit": 5}, 20 { 21 "$project": { 22 "_id": 1, 23 "title": 1, 24 "released": 1, 25 "genres": 1 26 } 27 } 28 ])
[ { _id: ObjectId("573a13acf29313caabd27afc"), genres: [ 'Comedy', 'Drama', 'Romance' ], title: 'Godfather' }, { _id: ObjectId("573a1396f29313caabce557f"), genres: [ 'Crime', 'Drama' ], title: 'The Godfather: Part II', released: ISODate("1974-12-20T00:00:00.000Z") }, { _id: ObjectId("573a1398f29313caabcebf7b"), genres: [ 'Crime', 'Drama' ], title: 'The Godfather: Part III', released: ISODate("1990-12-26T00:00:00.000Z") }, { _id: ObjectId("573a1399f29313caabceed8d"), genres: [ 'Action' ], title: 'The Defender', released: ISODate("1994-07-28T00:00:00.000Z") }, { _id: ObjectId("573a139af29313caabcef2a0"), genres: [ 'Action' ], title: 'The Enforcer', released: ISODate("1995-03-02T00:00:00.000Z") } ]
Los resultados de MongoDB Search incluyen documentos similares al término de consulta The Godfather en el género action. Sin embargo, no incluyen el documento excluido por su _id, que es ObjectId("573a1396f29313caabce4a9a").
Ejemplo 3: Múltiples analizadores
El siguiente ejemplo utiliza find() para identificar los documentos de entrada y, a continuación, utiliza el moreLikeThis operador para buscar documentos similares. En este ejemplo, la definición del índice utiliza asignaciones estáticas para indexar los campos de la sample_mflix.movies colección con diferentes analizadores. La definición del índice:
Configura un índice en los campos
_id,titleygenres.Analiza el campo
titleutilizando el analizadorlucene.standardy un analizador alternativo llamadokeywordAnalyzerque utiliza el analizadorlucene.keyword.Analiza y busca los campos utilizando el analizador
lucene.english.
1 { 2 "mappings": { 3 "dynamic": false, 4 "fields": { 5 "title": { 6 "type": "string", 7 "analyzer": "lucene.standard", 8 "multi": { 9 "keywordAnalyzer": { 10 "type": "string", 11 "analyzer": "lucene.keyword" 12 } 13 } 14 }, 15 "genres": { 16 "type": "string" 17 }, 18 "_id": { 19 "type": "objectId" 20 } 21 } 22 }, 23 "analyzer": "lucene.english" 24 }
Ejemplo
La siguiente consulta find() recupera las películas tituladas "Alicia en el País de las Maravillas" y almacena los resultados en movie. Especifica que los resultados solo deben contener los campos title y genres de los documentos coincidentes. Tenga en cuenta que, por defecto, el comando find() siempre devuelve el campo _id, cuyo valor podría variar en su clúster.
movie = db.movies.find( { title: "Alice in Wonderland" }, { genres: 1, title: 1} ).toArray
[ { _id: ObjectId("573a1394f29313caabcde9ef"), plot: 'Alice stumbles into the world of Wonderland. Will she get home? Not if the Queen of Hearts has her way.', title: 'Alice in Wonderland' }, { _id: ObjectId("573a1398f29313caabce963d"), plot: 'Alice is in Looking Glass land, where she meets many Looking Glass creatures and attempts to avoid the Jabberwocky, a monster that appears due to her being afraid.', title: 'Alice in Wonderland' }, { _id: ObjectId("573a1398f29313caabce9644"), plot: 'Alice is in Looking Glass land, where she meets many Looking Glass creatures and attempts to avoid the Jabberwocky, a monster that appears due to her being afraid.', title: 'Alice in Wonderland' }, { _id: ObjectId("573a139df29313caabcfb504"), plot: `The wizards behind The Odyssey (1997) and Merlin (1998) combine Lewis Carroll's "Alice in Wonderland" and "Through the Looking Glass" into a two-hour special that just gets curiouser and curiouser.`, title: 'Alice in Wonderland' }, { _id: ObjectId("573a13bdf29313caabd5933b"), plot: "Nineteen-year-old Alice returns to the magical world from her childhood adventure, where she reunites with her old friends and learns of her true destiny: to end the Red Queen's reign of terror.", title: 'Alice in Wonderland' } ]
El siguiente ejemplo utiliza un operador compuesto para consultar title genres los campos y utilizando las siguientes cláusulas:
La cláusula
shouldutiliza el operadormoreLikeThispara buscar documentos similares al documentomovie. Tenga en cuenta que el campotitlese analiza con los analizadoreslucene.standardylucene.keyword.La cláusula
mustNotespecifica que uno de los documentos de entrada, especificado por su valor_id, no debe incluirse en los resultados.
La consulta limita la lista de resultados a 10 documentos. Utiliza una etapa para $project incluir _id title genres los campos, y en los resultados.
Ejemplo
1 db.movies.aggregate([ 2 { 3 $search: { 4 "compound": { 5 "should": [{ 6 "moreLikeThis": { 7 "like": movie 8 } 9 }], 10 "mustNot": [ 11 { 12 "equals": { 13 "path": "_id", 14 "value": ObjectId ("573a1394f29313caabcde9ef") 15 } 16 }] 17 } 18 } 19 }, 20 { $limit: 10 }, 21 { 22 $project: { 23 "title": 1, 24 "genres": 1, 25 "_id": 1 26 } 27 } 28 ])
[ { _id: ObjectId("573a1398f29313caabce963d"), genres: [ 'Adventure', 'Family', 'Fantasy' ], title: 'Alice in Wonderland' }, { _id: ObjectId("573a1398f29313caabce9644"), genres: [ 'Adventure', 'Family', 'Fantasy' ], title: 'Alice in Wonderland' }, { _id: ObjectId("573a139df29313caabcfb504"), genres: [ 'Adventure', 'Comedy', 'Family' ], title: 'Alice in Wonderland' }, { _id: ObjectId("573a13bdf29313caabd5933b"), genres: [ 'Adventure', 'Family', 'Fantasy' ], title: 'Alice in Wonderland' }, { _id: ObjectId("573a1396f29313caabce3e7e"), genres: [ 'Comedy', 'Drama' ], title: 'Alex in Wonderland' }, { _id: ObjectId("573a13bdf29313caabd5a44b"), genres: [ 'Drama' ], title: 'Phoebe in Wonderland' }, { _id: ObjectId("573a139af29313caabcf0e23"), genres: [ 'Documentary' ], title: 'Wonderland' }, { _id: ObjectId("573a139ef29313caabcfcebc"), genres: [ 'Drama' ], title: 'Wonderland' }, { _id: ObjectId("573a13a0f29313caabd03dab"), genres: [ 'Drama' ], title: 'Wonderland' }, { _id: ObjectId("573a13abf29313caabd2372a"), genres: [ 'Crime', 'Drama', 'Mystery' ], title: 'Wonderland' } ]
La siguiente consulta utiliza explain con la consulta anterior para mostrar la disyunción (OR) que MongoDB Search construye para encontrar documentossimilares.
db.movies.explain("queryPlanner").aggregate([ { $search: { "compound": { "should": [{ "moreLikeThis": { "like": [{ "title": "Alice in Wonderland" }] } }], "mustNot": [ { "equals": { "path": "_id", "value": ObjectId ("573a1394f29313caabcde9ef") } }] } } }, { $limit: 10 }, { $project: { "title": 1, "genres": 1, "_id": 1 } } ])
{ explainVersion: '1', stages: [ { '$_internalSearchMongotRemote': { mongotQuery: { compound: { should: [ { moreLikeThis: { like: [ { title: 'Alice in Wonderland' } ] } } ], mustNot: [ { equals: { path: '_id', value: ObjectId("573a1394f29313caabcde9ef") } } ] } }, explain: { type: 'BooleanQuery', args: { must: [], mustNot: [ { path: 'compound.mustNot', type: 'ConstantScoreQuery', args: { query: { type: 'TermQuery', args: { path: '_id', value: '[57 3a 13 94 f2 93 13 ca ab cd e9 ef]' } } } } ], should: [ { path: 'compound.should', type: 'BooleanQuery', args: { must: [], mustNot: [], should: [ { type: 'TermQuery', args: { path: 'title', value: 'in' } }, { type: 'TermQuery', args: { path: 'title.keywordAnalyzer', value: 'Alice in Wonderland' } }, { type: 'TermQuery', args: { path: 'title', value: 'wonderland' } }, { type: 'TermQuery', args: { path: 'title', value: 'alice' } } ], filter: [], minimumShouldMatch: 0 } } ], filter: [], minimumShouldMatch: 0 } } } }, { '$_internalSearchIdLookup': {} }, { '$limit': Long("10") }, { '$project': { _id: true, title: true, genres: true } } ], serverInfo: { ... }, serverParameters: { ... }, command: { aggregate: 'movies', pipeline: [ { '$search': { compound: { should: [ { moreLikeThis: { like: [ { title: 'Alice in Wonderland' } ] } } ], mustNot: [ { equals: { path: '_id', value: ObjectId("573a1394f29313caabcde9ef") } } ] } } }, { '$limit': 10 }, { '$project': { title: 1, genres: 1, _id: 1 } } ], cursor: {}, '$db': 'sample_mflix' }, ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1659133479, i: 1 }), signature: { hash: Binary(Buffer.from("865d9ef1187ae1a74c4a0da1e29882aebcf2be7c", "hex"), 0), keyId: Long("7123262728533180420") } }, operationTime: Timestamp({ t: 1659133479, i: 1 }) }