MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB $mergeObjects

In MongoDB sind die $mergeObjects Aggregation Pipeline Operator kombiniert mehrere Dokumente zu einem einzigen Dokument.

Syntax

Die $mergeObjects Operator unterstützt zwei Syntaxen.

Syntax 1:

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

Syntax 2:

{ $mergeObjects: <document> }

Die erste Syntax akzeptiert mehrere Argumente und die zweite Syntax akzeptiert ein Argument.

Beispiel für Syntax 1 (mehrere Argumente)

Die erste Syntax beinhaltet die Bereitstellung von $mergeObjects mit mehr als einem Argument/Dokument. $mergeObjects kombiniert dann diese Dokumente zu einem.

Angenommen, wir haben eine Sammlung namens users mit folgendem Dokument:

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

Wir können $mergeObjects verwenden um den name zusammenzuführen und contact Felder:

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

Ergebnis:

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

In diesem Fall haben wir beide Felder zu einem einzigen Feld namens user zusammengeführt . Wenn wir mehr Felder/Dokumente hätten, hätten wir diese auch zusammenführen können, wenn wir wollten.

Doppelte Feldnamen

Wenn die zusammenzuführenden Dokumente doppelte Feldnamen enthalten, wird $mergeObjects überschreibt das Feld beim Zusammenführen der Dokumente. Daher enthält das Feld im resultierenden Dokument den Wert aus dem letzten Dokument, das für dieses Feld zusammengeführt wurde.

Angenommen, wir haben das folgende Dokument:

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

Wir können sehen, dass beide Dokumente ein Feld namens f_name enthalten .

Folgendes passiert, wenn wir diese Dokumente zusammenführen:

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

Ergebnis:

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

Der f_name Feld im resultierenden Dokument enthält Bart , das ist der Wert aus dem zuletzt zusammengeführten Dokument.

Nullwerte

Beim Zusammenführen eines Dokuments mit null , wird das resultierende Dokument ohne Änderungen zurückgegeben.

Aber wenn alle zusammenzuführenden Dokumente null sind , dann wird ein leeres Dokument zurückgegeben.

Angenommen, wir haben die folgenden Dokumente:

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

Folgendes passiert, wenn wir name zusammenführen und contact Felder in diesen beiden Dokumenten:

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

Ergebnis:

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

Beispiele für Syntax 2 (Einzelargument)

Hier sind zwei Beispiele, die die Syntax mit einem einzigen Argument verwenden.

$group Stufenakkumulator

Im ersten Beispiel $mergeObjects wird als $group verwendet Stufenakkumulator.

Angenommen, wir haben eine Sammlung namens products mit folgenden Dokumenten:

{
	"_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
	}
}

Wir können diese Dokumente nach ihrem product gruppieren Feld und verwenden Sie dann $mergeObjects um das inventory zusammenzuführen Feld für jede Gruppe:

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

Ergebnis:

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

Arrays

Dieses Beispiel wendet $mergeObjects an zu einem einzelnen Dokument, das ein Feld mit einem Array von Dokumenten enthält.

Angenommen, wir haben eine Sammlung namens test mit folgenden Dokumenten:

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

Wir können $mergeObjects anwenden zu den data Feld:

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

Ergebnis:

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

Fehlende Felder

$mergeObjects ignoriert alle fehlenden Felder. Das heißt, wenn Sie ein Feld angeben, das nicht vorhanden ist, wird es ignoriert. Wenn keines der Felder vorhanden ist, wird ein leeres Dokument zurückgegeben.

Beispiel:

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

Ergebnis:

{ "_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" : { } }

Folgendes passiert jedoch, wenn keine der Felder existieren:

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

Ergebnis:

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

Das Ergebnis ist ein leeres Dokument.

Das Gleiche gilt für die Verwendung der Ein-Argument-Syntax.

Beispiel:

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

Ergebnis:

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