MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

MongoDB $mergeObjects

Dans MongoDB, les $mergeObjects l'opérateur de pipeline d'agrégation combine plusieurs documents en un seul document.

Syntaxe

Les $mergeObjects L'opérateur prend en charge deux syntaxes.

Syntaxe 1 :

{ $mergeObjects: [ <document1>, <document2>, ... ] }

Syntaxe 2 :

{ $mergeObjects: <document> }

La première syntaxe accepte plusieurs arguments et la seconde syntaxe accepte un argument.

Exemple de syntaxe 1 (arguments multiples)

La première syntaxe consiste à fournir $mergeObjects avec plus d'un argument/document. $mergeObjects combine ensuite ces documents en un seul.

Supposons que nous ayons une collection appelée users avec le document suivant :

{
	"_id" : 1,
	"name" : {
		"f_name" : "Homer",
		"l_name" : "Simpson"
	},
	"contact" : {
		"email" : "[email protected]",
		"ph" : null
	}
}

Nous pouvons utiliser $mergeObjects pour fusionner le name et contact champs :

db.users.aggregate(
  [
    {
      $project:
        { 
          user: { $mergeObjects: [ "$name", "$contact" ] }
        }
    }
  ]
).pretty()

Résultat :

{
	"_id" : 1,
	"user" : {
		"f_name" : "Homer",
		"l_name" : "Simpson",
		"email" : "[email protected]",
		"ph" : null
	}
}

Dans ce cas, nous avons fusionné les deux champs en un seul champ appelé user . Si nous avions plus de champs/documents, nous aurions pu les fusionner aussi si nous le voulions.

Noms de champs en double

Si les documents à fusionner contiennent des noms de champs en double, $mergeObjects écrase le champ lors de la fusion des documents. Par conséquent, le champ du document résultant contient la valeur du dernier document fusionné pour ce champ.

Supposons que nous ayons le document suivant :

{
	"_id" : 2,
	"name" : {
		"f_name" : "Peter",
		"l_name" : "Griffin"
	},
	"contact" : {
		"email" : "[email protected]",
		"f_name" : "Bart"
	}
}

Nous pouvons voir que les deux documents contiennent un champ nommé f_name .

Voici ce qui se passe lorsque nous fusionnons ces documents :

db.users.aggregate(
  [
    { $match: { _id: 2 } },
    {
      $project:
        { 
          user: { $mergeObjects: [ "$name", "$contact" ] }
        }
    }
  ]
).pretty()

Résultat :

{
	"_id" : 2,
	"user" : {
		"f_name" : "Bart",
		"l_name" : "Griffin",
		"email" : "[email protected]"
	}
}

Le f_name champ dans le document résultant contient Bart , qui est la valeur du dernier document qui a été fusionné.

Valeurs nulles

Si vous fusionnez un document avec null , le document résultant sera renvoyé sans aucune modification.

Mais si tous les documents à fusionner sont null , un document vide est renvoyé.

Supposons que nous ayons les documents suivants :

{
	"_id" : 3,
	"name" : {
		"f_name" : "Hubert",
		"l_name" : "Farnsworth"
	},
	"contact" : null
}
{ "_id" : 4, "name" : null, "contact" : null }

Voici ce qui se passe lorsque nous fusionnons le name et contact champs dans ces deux documents :

db.users.aggregate(
  [
    { $match: { _id: { $in: [ 3, 4 ] } } },
    {
      $project:
        { 
          user: { $mergeObjects: [ "$name", "$contact" ] }
        }
    }
  ]
)

Résultat :

{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } }
{ "_id" : 4, "user" : {  } }

Exemples de syntaxe 2 (argument unique)

Voici deux exemples qui utilisent la syntaxe à argument unique.

$group Accumulateur d'étape

Dans le premier exemple, $mergeObjects est utilisé comme un $group accumulateur d'étage.

Supposons que nous ayons une collection appelée products avec les documents suivants :

{
	"_id" : 1,
	"product" : "Shirt",
	"inventory" : {
		"blue" : 10,
		"red" : 2
	}
}
{
	"_id" : 2,
	"product" : "Shirt",
	"inventory" : {
		"green" : 3,
		"black" : 1
	}
}
{
	"_id" : 3,
	"product" : "Shorts",
	"inventory" : {
		"blue" : 2,
		"red" : 8
	}
}
{
	"_id" : 4,
	"product" : "Shorts",
	"inventory" : {
		"green" : 5,
		"black" : 3
	}
}

Nous pouvons regrouper ces documents par leur product champ, puis utilisez $mergeObjects pour fusionner l'inventory champ pour chaque groupe :

db.products.aggregate( [
   { $group: { 
     _id: "$product", 
     mergedProducts: { $mergeObjects: "$inventory" } 
     } 
    }
]).pretty()

Résultat :

{
	"_id" : "Shorts",
	"mergedProducts" : {
		"blue" : 2,
		"red" : 8,
		"green" : 5,
		"black" : 3
	}
}
{
	"_id" : "Shirt",
	"mergedProducts" : {
		"blue" : 10,
		"red" : 2,
		"green" : 3,
		"black" : 1
	}
}

Tableaux

Cet exemple applique $mergeObjects à un seul document qui contient un champ avec un tableau de documents.

Supposons que nous ayons une collection appelée test avec les documents suivants :

{
	"_id" : 1,
	"data" : [
		{
			"a" : 1,
			"b" : 2
		},
		{
			"c" : 3,
			"d" : 4
		}
	]
}

Nous pouvons appliquer $mergeObjects aux data champ :

db.test.aggregate(
  [
    {
      $project:
        { 
          result: { $mergeObjects: "$data" }
        }
    }
  ]
)

Résultat :

{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } }

Champs manquants

$mergeObjects ignore les champs manquants. Autrement dit, si vous fournissez un champ qui n'existe pas, il l'ignore. Si aucun des champs n'existe, il renvoie un document vide.

Exemple :

db.users.aggregate(
  [
    {
      $project:
        { 
          user: { $mergeObjects: [ "$name", "$oops" ] }
        }
    }
  ]
).pretty()

Résultat :

{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson" } }
{ "_id" : 2, "user" : { "f_name" : "Peter", "l_name" : "Griffin" } }
{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } }
{ "_id" : 4, "user" : { } }

Cependant, voici ce qui se passe lorsque aucun des champs existent :

db.users.aggregate(
  [
    {
      $project:
        { 
          user: { $mergeObjects: [ "$wrong", "$oops" ] }
        }
    }
  ]
).pretty()

Résultat :

{ "_id" : 1, "user" : { } }
{ "_id" : 2, "user" : { } }
{ "_id" : 3, "user" : { } }
{ "_id" : 4, "user" : { } }

Le résultat est un document vide.

C'est la même chose lorsque vous utilisez la syntaxe à argument unique.

Exemple :

db.products.aggregate( [
   { $group: { 
     _id: "$product", 
     mergedProducts: { $mergeObjects: "$oops!" } 
     } 
    }
]).pretty()

Résultat :

{ "_id" : "Shorts", "mergedProducts" : { } }
{ "_id" : "Shirt", "mergedProducts" : { } }