sql >> Databáze >  >> NoSQL >> MongoDB

MongoDb :Najděte společný prvek ze dvou polí v dotazu

Existuje několik přístupů, jak dělat, co chcete, záleží jen na vaší verzi MongoDB. Stačí odeslat odpovědi shellu. Obsah je v podstatě reprezentace JSON, kterou není těžké přeložit pro entity DBObject v Javě nebo JavaScript, který se má spustit na serveru, takže se to opravdu nemění.

První a nejrychlejší přístup je s MongoDB 2.6 a vyšší, kde získáte novou sadu operací:

var test = [ "t3", "t4", "t5" ];

db.collection.aggregate([
   { "$match": { "tags": {"$in": test } }},
   { "$project": {
       "tagMatch": {
           "$setIntersection": [
               "$tags",
               test
           ]
       },
       "sizeMatch": {
           "$size": {
               "$setIntersection": [
                   "$tags",
                   test
               ]
           }
       }
   }},
   { "$match": { "sizeMatch": { "$gte": 1 } } },
   { "$project": { "tagMatch": 1 } }
])

Nové operátory jsou $setIntersection která dělá hlavní práci a také $ velikost operátor, který měří velikost pole a pomáhá při druhém filtrování. To skončí jako základní srovnání „množin“ za účelem nalezení položek, které se protínají.

Pokud máte starší verzi MongoDB, je to stále možné, ale potřebujete několik dalších fází a to může poněkud ovlivnit výkon v závislosti na tom, zda máte velká pole:

var test = [ "t3", "t4", "t5" ];

db.collection.aggregate([
   { "$match": { "tags": {"$in": test } }},
   { "$project": {
      "tags": 1,
      "match": { "$const": test }
   }},
   { "$unwind": "$tags" },
   { "$unwind": "$match" },
   { "$project": {
       "tags": 1,
       "matched": { "$eq": [ "$tags", "$match" ] }
   }},
   { "$match": { "matched": true }},
   { "$group": {
       "_id": "$_id",
       "tagMatch": { "$push": "$tags" },
       "count": { "$sum": 1 }
   }}
   { "$match": { "count": { "$gte": 1 } }},
   { "$project": { "tagMatch": 1 }}
])

Nebo pokud se zdá, že se to všechno týká nebo jsou vaše pole dostatečně velká na to, aby způsobila rozdíl ve výkonu, pak vždy existuje mapReduce :

var test = [ "t3", "t4", "t5" ];

db.collection.mapReduce(
    function () {
      var intersection = this.tags.filter(function(x){
          return ( test.indexOf( x ) != -1 );
      });
      if ( intersection.length > 0 ) 
          emit ( this._id, intersection );
   },
   function(){},
   {
       "query": { "tags": { "$in": test } },
       "scope": { "test": test },
       "output": { "inline": 1 }
   }
)

Upozorňujeme, že ve všech případech $in operátor vám stále pomáhá snížit výsledky, i když to není úplná shoda. Dalším společným prvkem je kontrola „velikost“ výsledku křižovatky, aby se snížila odezva.

Vše lze snadno naprogramovat, přesvědčte šéfa, aby přešel na MongoDB 2.6 nebo vyšší, pokud tam ještě nejste, abyste dosáhli nejlepších výsledků.




  1. Správa žurnálování v MongoDB

  2. Provozní dostupnost databáze

  3. Mongodb atlas + node.js funguje lokálně, ale zastaví se, když se přesune do Heroku

  4. Třídy Mongo se v konzolové aplikaci Yii nenačítají automaticky