MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

MongoDb :Znajdź wspólny element z dwóch tablic w zapytaniu

Istnieje kilka sposobów na zrobienie tego, co chcesz, zależy to tylko od twojej wersji MongoDB. Wystarczy przesłać odpowiedzi powłoki. Zawartość jest w zasadzie reprezentacją JSON, która nie jest trudna do przetłumaczenia dla jednostek DBObject w Javie lub JavaScript do wykonania na serwerze, więc tak naprawdę się nie zmienia.

Pierwsze i najszybsze podejście dotyczy MongoDB 2.6 i nowszych, gdzie otrzymujesz nowe operacje na zestawach:

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 } }
])

Nowe operatory to $setIntersection który wykonuje główną pracę, a także $ rozmiar operator, który mierzy rozmiar tablicy i pomaga w drugim filtrowaniu. To kończy się podstawowym porównaniem „zestawów” w celu znalezienia elementów, które się przecinają.

Jeśli masz wcześniejszą wersję MongoDB, nadal jest to możliwe, ale potrzebujesz kilku dodatkowych etapów, co może nieco wpłynąć na wydajność, w zależności od dużych tablic:

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 }}
])

Lub jeśli wszystko to wydaje się być zaangażowane lub twoje tablice są wystarczająco duże, aby spowodować różnicę w wydajności, zawsze jest 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 }
   }
)

Pamiętaj, że we wszystkich przypadkach $in operator nadal pomaga zredukować wyniki, nawet jeśli nie jest to pełne dopasowanie. Innym wspólnym elementem jest sprawdzanie „rozmiaru” wyniku przecięcia w celu zmniejszenia odpowiedzi.

Wszystko jest dość łatwe do zakodowania, przekonaj szefa, aby przełączył się na MongoDB 2.6 lub nowszy, jeśli jeszcze nie jesteś tam, aby uzyskać najlepsze wyniki.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Korzystanie ze zmiennych w instrukcji aktualizacji MongoDB

  2. Nie można połączyć się z MongoDB Atlas przy użyciu Mongoose z parametrami połączenia

  3. MongoDB:Sortuj według istniejących pól, a następnie alfabetycznie

  4. Jak skonfigurować replikację MySQL Master-Slave na Ubuntu 18.04

  5. Wstaw dane do Meteora z Facebook API