Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.
Menu Docs

Associações incorporadas

Associações no Mongoid permitem criar relacionamentos entre modelos. Neste guia, você pode aprender a usar associações incorporadas para armazenar diferentes tipos de documentos na mesma coleção. O Mongoid suporta associações incorporadas com as seguintes macros:

  • embeds_one

  • embeds_many

  • embedded_in

  • recursively_embeds_one

  • recursively_embeds_many

As seções a seguir descrevem como usar esses tipos de associação.

Para especificar que um modelo de classe contém um documento incorporado de um tipo de classe diferente, use a macro embeds_one na classe principal e a macro embedded_in na classe incorporada. O exemplo a seguir cria uma classe Band com uma classe Label incorporada :

class Band
include Mongoid::Document
embeds_one :label
end
class Label
include Mongoid::Document
field :name, type: String
embedded_in :band
end

O Mongoid armazena documentos incorporados com a macro embeds_one no documento principal como um campo com o mesmo nome da classe incorporada. Os documentos Label anteriores são armazenados no documento Band, conforme mostrado no exemplo a seguir:

# Band document
{
"_id" : ObjectId("..."),
"label" : {
"_id" : ObjectId("..."),
"name" : "Periphery",
}
}

Você pode armazenar o documento incorporado com um nome diferente usando a opção store_as, conforme mostrado no exemplo a seguir:

class Band
include Mongoid::Document
embeds_one :label, store_as: "record_label"
end

Para especificar que um modelo de classe contém vários documentos incorporados de um tipo de classe diferente, use a macro embeds_many na classe principal e a macro embedded_in na classe incorporada. O exemplo a seguir cria uma classe Band com vários documentos do tipo Album incorporados:

class Band
include Mongoid::Document
embeds_many :albums
end
class Album
include Mongoid::Document
field :name, type: String
embedded_in :band
end

O Mongoid armazena documentos incorporados com a macro embeds_many no documento principal como um campo de array com o mesmo nome da classe incorporada. Os documentos Album anteriores são armazenados no documento Band, conforme mostrado no exemplo a seguir:

{
"_id" : ObjectId("..."),
"albums" : [
{
"_id" : ObjectId("..."),
"name" : "Omega",
}
]
}

Você pode armazenar o documento incorporado com um nome diferente usando a opção store_as, conforme mostrado no exemplo a seguir:

class Band
include Mongoid::Document
embeds_many :albums, store_as: "records"
end

Você pode incorporar um ou mais documentos do mesmo tipo em uma classe principal usando as macros recursively_embeds_one e recursively_embeds_many. Ambas as macros fornecem acessadores para os documentos pai e filho por meio de um método parent_* e um método child_*, em que * representa o nome da classe. O exemplo a seguir cria uma classe Band que incorpora recursivamente vários outros documentos Band para representar vários nomes de bandas:

class Band
include Mongoid::Document
field :name, type: String
recursively_embeds_many
end

Você pode acessar os documentos principal e secundário por meio dos métodos parent_band e child_band, conforme mostrado no exemplo a seguir:

root = Band.new(name: "Linkin Park")
# Add child bands
child_one = root.child_band.build(name: "Lincoln Park")
child_two = root.child_band.build(name: "Xero")
# Access parent band
child_one.parent_band
# Outputs: root

Você pode acessar documentos incorporados ao consultar a collection da classe principal usando a notação de ponto.

O exemplo a seguir usa notação de ponto para consultar documentos do tipo Tour que estão incorporados em uma classe Band . A query retorna documentos com um valor tours.year de 2000 ou superior:

Band.where('tours.year' => {'$gte' => 2000})

Você pode usar o método de projeção pluck para recuperar documentos incorporados sem recuperar seus documentos pai associados, conforme mostrado no exemplo a seguir:

# Get awards for bands that have toured since 2000
Band.where('tours.year' => {'$gte' => 2000}).pluck(:awards)

Você pode usar os métodos de query do Mongoid para realizar a correspondência incorporada, o que permite consultar associações incorporadas de documentos que já estão carregados no aplicação. O Mongoid implementa a correspondência incorporada sem enviar queries para o servidor.

Os seguintes operadores de query são compatíveis com correspondência incorporada:

O exemplo a seguir consulta o campo tours incorporado de um documento Band carregado usando o operador de comparação $gte:

band = Band.where(name: 'Astral Projection').first
tours = band.tours.where(year: {'$gte' => 2000})

A correspondência incorporada em documentos carregados tem as seguintes limitações conhecidas:

  • A correspondência incorporada não está implementada para as seguintes funcionalidades:

  • O Mongoid expande os argumentos Range para hashes com condições $gte e $lte. Isso pode levar a queries inválidas em alguns casos e gera uma exceção InvalidQuery.

  • Com o operador $regex, você não pode especificar um objeto de expressão regular como um padrão e, ao mesmo tempo, fornecer opções para o campo $options. Você só pode fornecer opções se o padrão de expressão regular for uma string.

Por padrão, o Mongoid adiciona um campo _id aos documentos incorporados. Você pode omitir esse campo de documentos incorporados especificando explicitamente o campo _id em seu modelo e omitindo o valor padrão. O exemplo a seguir instrui o Mongoid a não adicionar um campo _id à classe Albums :

class Album
include Mongoid::Document
field :name, type: String
field :_id, type: Object
embedded_in :band
end

Na classe Albums anterior, o campo _id não é adicionado automaticamente. Sem um valor padrão, o Mongoid não armazena o valor no banco de dados, a menos que você forneça um em seu modelo.

Você pode excluir documentos filhos de associações embeds_many usando um dos seguintes métodos:

  • clear

  • delete_all

  • destroy_all

The clear method uses the $unset operator operator to remove an entire embedded association from the parent document. The clear method does not run any destroy callbacks. The following example uses the clear method to remove all embedded associations from the Band class:

band = Band.find(...)
band.tours.clear

The delete_all method uses the $pullAll operator operator to remove documents in an embedded association. delete_all loads the association if it has not yet been loaded, then only removes the documents that exist in the application. The delete_all method does not run any destroy callbacks. The following example uses the delete_all method to remove all embedded Album documents from the Band class:

band = Band.find(...)
band.tours.delete_all

The destroy_all method also uses the $pullAll operator operator to remove documents in an embedded association. It also runs any destroy callbacks that are defined on the associated documents. The following example uses the destroy_all method to remove all embedded Album documents from the Band class:

band = Band.find(...)
band.tours.destroy_all