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

Znajdowanie dwóch elementów w tablicy dokumentów, które pojawiają się w określonej kolejności

Jeśli chcesz tego rodzaju ograniczenia w zapytaniu, masz zasadniczo dwie opcje, w zależności od tego, co obsługuje Twoja wersja MongoDB:

MongoDB 3.6

Najlepiej użyć $expr „dodatkowo” do dowolnych normalnych warunków zapytania, aby wybrać prawidłowe dokumenty:

var A = 10, B = 40;

Model.find({
  "subDocs.value": { "$all": [A, B] },
  "$expr": {
    "$lt": [
      { "$arrayElemAt": [
        "$subDocs.index",
        { "$indexOfArray": [ "$subDocs.value", A ]}
      ]},
      { "$arrayElemAt": [
        "$subDocs.index",
        { "$indexOfArray": [ "$subDocs.value", B ]}  
      ]}
    ]
  }
})

Lub pasujące do „ostatniego” wystąpienie:

Model.find({
  "subDocs.value": { "$all": [A, B] },
  "$expr": {
    "$lt": [
      { "$arrayElemAt": [
        "$subDocs.index",
        { "$subtract": [
          { "$subtract": [{ "$size": "$subDocs.value" }, 1 ] },
          { "$indexOfArray": [ { "$reverseArray": "$subDocs.value" }, A ] }
        ]}
      ]},
      { "$arrayElemAt": [
        "$subDocs.index",
        { "$subtract": [
          { "$subtract": [{ "$size": "$subDocs.value" }, 1 ] },
          { "$indexOfArray": [ { "$reverseArray": "$subDocs.value" }, B ] }
        ]}
      ]}
    ]
  }
})

Wcześniejsze wersje

To samo, ale bez natywnych operatorów musisz użyć oceny JavaScript $gdzie :

var A = 10, B = 40;

Model.find({
  "subDocs.value": { "$all": [A, B] },
  "$where": `this.subDocs.find( e => e.value === ${A}).index
      < this.subDocs.find( e => e.value === ${B}).index`
})

Lub pasujące do „ostatniego” wystąpienie:

Model.find({
  "subDocs.value": { "$all": [10,40] },
  "$where": `let arr = this.subDocs.reverse();
      return arr.find( e => e.value === ${A}).index
        > arr.find( e => e.value === ${B}).index`
})

Jeśli potrzebujesz tego w potoku agregacji, użyjesz $redaguj i podobna logika do pierwszego przykładu:

var A = 10, B = 40;

Model.aggregate([
  { "$match": { "subDocs.value": { "$all": [A, B] } } },
  { "$redact": {
    "$cond": {
      "if": {
        "$lt": [
          { "$arrayElemAt": [
            "$subDocs.index",
            { "$indexOfArray": [ "$subDocs.value", A ]}
          ]},
          { "$arrayElemAt": [
            "$subDocs.index",
            { "$indexOfArray": [ "$subDocs.value", B ]}  
          ]}
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

Wystarczy powiedzieć, że „logika porównania” nie jest w rzeczywistości natywna dla samych „wyrażeń operatora zapytania”, więc jest to jedyna część, która „optymalnie” można zastosować do indeksu przy użyciu $all operator zapytania we wszystkich przypadkach. Podstawowa pozostała logika faktycznie ma zastosowanie „po” tym, że główne wyrażenie jest oceniane i „dodatkowo do”, aby żadne wyniki nie zostały zwrócone poza tymi, które spełniają wyrażenie z $expr lub $where .

Podstawową logiką każdego z nich jest wyodrębnienie wartości "indeksu" właściwość z "pierwszego" elementu tablicy, który faktycznie pasuje do odpowiedniej wartości w "value" własność. Jeżeli jest to „mniejsze niż”, wtedy warunek jest prawda a to odpowiada zwracanemu dokumentowi.

Zwróć więc uwagę, że albo „obliczona ocena” odpowiada wydajności operatorów zapytań i bez użycia „w połączeniu” innych warunków operatora zapytań, które są w stanie uzyskać dostęp do „indeksu”, zostanie zainicjowane „pełne skanowanie kolekcji”.

Ale ogólny wynik jest z pewnością bardziej wydajny niż zwracanie wszystkich pasujących elementów do pierwszego warunku zapytania, a następnie odrzucanie ich na kursorze „po” powrocie z bazy danych.

Zobacz także dokumentację $arrayElemAt , $indexOfArray , $lt i Array.find() dla JavaScript




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mock/testowanie bazy danych Mongodb Node.js

  2. MongoDB C# Query Array of Objects, która zawiera wartość właściwości

  3. Problemy z konfiguracją użytkowników i połączeniem z Mongo za pomocą PHP

  4. Konwertowanie BSON Type ObjectId na JSON (przechowywanie w Mongodb) — Java

  5. Kolekcja w kolekcji