moreLikeThis
Definição
Comportamento
Quando você gera uma query moreLikeThis
, o Atlas Search executa estas ações:
Extrai um número limitado de termos mais representativos com base nos documentos de entrada especificados na opção
like
do operador.Cria uma consulta de disjunção (OR) para encontrar documentos semelhantes com base nos termos mais representativos e retorna os resultados.
O operador moreLikeThis
realiza uma pesquisa de documentos semelhantes usando o analisador que você especificar na configuração de índice. Se você omitir o analisador na definição de índice, o operador moreLikeThis
utilizará o analisador padrão. Se você especificar vários analisadores, o operador moreLikeThis
executará o texto de entrada em cada analisador, pesquisará e retornará os resultados de todos os analisadores.
Para visualizar a disjunção (OU) que o Atlas Search cria para encontrar documentos semelhantes, use explicar com sua query de operador moreLikeThis
.
Uso
Antes de executar a query do operador moreLikeThis
, recomendamos que você recupere um ou mais documentos de entrada. Para recuperar documentos de entrada, você pode fazer o seguinte:
Execute uma consulta, como find(), ou outra consulta MQL para localizar documentos BSON.
Execute qualquer pipeline de agregação que retorne documentos BSON.
Usar qualquer outra fonte de documentos em seu aplicativo.
Depois de identificar os documentos de entrada, você pode passá-los ao operador moreLikeThis
.
Quando você gera uma query de operador moreLikeThis
, o Atlas Search retorna o documento de entrada original nos resultados. Para omitir o documento de entrada dos resultados da query, use o operador moreLikeThis
em uma query de operador composto e exclua o documento de entrada pelo seu _id
usando o operador equals
na cláusula mustNot.
Sintaxe
moreLikeThis
tem a seguinte sintaxe:
{ "$search": { "index": index name, // optional, defaults to "default" "moreLikeThis": { "like": [ { <"field-name">: <"field-value">, ... }, ... ], "score": <options> } } }
Opções
moreLikeThis
usa a seguinte opção para criar uma consulta:
Campo | Tipo | Descrição | necessidade |
---|---|---|---|
| um documento BSON ou uma matriz de documentos | Um ou mais documentos BSON que o Atlas Search utiliza para extrair termos representativos para consulta. | Obrigatório |
| objeto | Pontuação a ser atribuída aos resultados de pesquisa correspondentes. Você pode modificar a pontuação padrão usando as seguintes opções:
Para obter informações sobre como utilizar o Quando você faz query de valores em arrays, o Atlas Search não altera a pontuação dos resultados correspondentes com base no número de valores dentro da array que correspondeu à query. A pontuação seria igual a uma única correspondência, independentemente do número de correspondências dentro de uma array. | Opcional |
Limitações
Você não pode utilizar o operador moreLikeThis
para consultar valores que não são strings. Para pesquisar valores que não sejam strings, você pode combinar uma consulta moreLikeThis
com um operador near, range ou qualquer outro em uma consulta de operador composto .
Você não pode usar o operador moreLikeThis
dentro do operador embeddedDocument para consultar documentos em um array.
Exemplos
Os exemplos usam a collection movies
no banco de dados sample_mflix
. Cada exemplo nesta seção utiliza uma definição de índice diferente para demonstrar diferentes funcionalidades do operador.
Antes de executar as queries de exemplo no seu cluster, carregue os dados de amostra no seu cluster do Atlas e crie o índice sugerido. Para saber mais sobre como criar um índice do Atlas Search usando a UI, API o CLI, consulte Como criar um índice do Atlas Search. As definições de índice usam o nome default
.
Se você nomear seu índice default
, não precisará especificar um parâmetro index
no estágio do pipeline $search . Se você der um nome personalizado ao seu índice, deverá especificar este nome no parâmetro index
.
Exemplo 1: documento único com vários campos
O exemplo seguinte utiliza o operador moreLikeThis
para localizar documentos que são semelhantes aos valores de campo múltiplos. Para este exemplo, a definição do índice contém mapeamentos dinâmicos para indexar dinamicamente todos os tipos de campos indexáveis dinamicamente na collection. Sua definição de índice para a collection sample_mflix.movies
deve ser semelhante à seguinte.
{ "mappings": { "dynamic": true } }
Exemplo
A consulta a seguir pesquisa filmes semelhantes ao título do filme de entrada "O Poderoso Chefão" e ao gênero de filme de entrada "ação". Ele inclui um estágio $limit
para limitar a saída a 5
resultados e um estágio $project
para excluir todos os campos, exceto title
, released
e genres
.
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") } ]
Os resultados do Atlas Search contêm filmes semelhantes ao título do filme de entrada " O Poderoso Chefão " e ao gênero de filme de entrada " action ".
Exemplo 2: Documento de entrada excluído nos resultados
O exemplo a seguir usa find()
para identificar um documento de entrada e, em seguida, usa o operador moreLikeThis
para localizar documentos semelhantes. Neste exemplo, a definição do índice usa mapeamentos estáticos para indexar apenas os campos title
, genres
e _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 }
Exemplo
A consulta find()
a seguir localiza o filme com o título "O Poderoso Chefão" e armazena o resultado dentro de movie
. Especifica que os resultados devem conter somente os campos title
e genres
para os documentos correspondentes. Por padrão, o comando find
()
sempre retorna o campo _id
, e o valor dele pode ser diferente no seu cluster.
movie = db.movies.find( { title: "The Godfather" }, { genres: 1, title: 1} ).toArray()
[ { _id: ObjectId("573a1396f29313caabce4a9a"), genres: [ 'Crime', 'Drama' ], title: 'The Godfather' } ]
A seguinte query usa um operador composto com o operador moreLikeThis
para fazer query no campos title
e genres
, e o operador de igual para excluir o documento de entrada utilizando as seguintes cláusulas:
A cláusula
must
para executar a query de filmes semelhantes ao filme armazenado emmovie
.A cláusula
mustNot
para excluir o documento de entrada dos resultados por seu valor_id
. Note que o valor_id
utilizado na query corresponde ao valor_id
nos resultados da queryfind()
anterior.
A query limita a saída a 5
resultados. Além disso, a query utiliza um estágio do $project
para incluir os campos _id
, title
, released
e genres
nos resultados.
Observação
Antes de executar esta query, substitua o valor do campo _id
na linha 13 pelo valor do campo _id
nos resultados da query.
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") } ]
Os resultados do Atlas Search incluem documentos semelhantes ao termo da query The Godfather
no gênero action
. No entanto, os resultados não incluem o documento que foi excluído pelo seu _id
, que é ObjectId("573a1396f29313caabce4a9a")
.
Exemplo 3: Vários analyzers
O exemplo a seguir usa find()
para identificar documentos de entrada e, em seguida, usa um operador moreLikeThis
para encontrar documentos semelhantes. Neste exemplo, a definição do índice usa mapeamentos estáticos para indexar os campos na collection sample_mflix.movies
com analisadores diferentes. A definição do índice:
Configura um índice nos campos
_id
,title
egenres
.Analisa o campo
title
utilizando o analisadorlucene.standard
e um analisador alternativo denominadokeywordAnalyzer
que utiliza o analisadorlucene.keyword
.Analisa e pesquisa os campos utilizando o analyzer
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 }
Exemplo
A consulta find()
a seguir detecta os filmes com o título "Alice no País das Maravilhas" e armazena os resultados em movie
. Especifica que os resultados devem conter somente os campos title
e genres
para os documentos correspondentes. Por padrão, o comando find()
sempre retorna o campo _id
, e o valor dele pode ser diferente no seu cluster.
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' } ]
O exemplo a seguir utiliza um operador composto para consultar os campos title
e genres
utilizando as seguintes cláusulas:
A cláusula
should
usa o operadormoreLikeThis
para pesquisar documentos semelhantes ao documento nomovie
. Note que o campotitle
é analisado com os analisadoreslucene.standard
elucene.keyword
.A cláusula
mustNot
especifica que um dos documentos de entrada, especificado pelo seu valor_id
, não deve ser incluído nos resultados.
A query limita a lista de resultados a 10
documentos. Além disso, a query utiliza um estágio do $project
para incluir os campos _id
, title
e genres
nos resultados.
Exemplo
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' } ]
A query abaixo usa explicar com a query anterior para mostrar a disjunção (OU) que o Atlas Search constrói para localizar documentos semelhantes.
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 }) }