kzen.dev
  • Întrebări
  • Tag-uri
  • Utilizatori
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
 skerit
skerit
Question

Găsi MongoDB înregistrările unde matrice domeniu nu este gol

Toate înregistrările au un câmp numit "imagini". Acest domeniu este o matrice de siruri de caractere.

Vreau acum cele mai noi de 10 de înregistrări în cazul în care această matrice NU ESTE gol.

Am'am căutat pe google, dar destul de ciudat m-am't a găsit de mult pe asta. Am'am citit în $unde opțiune, dar mă întrebam cum de lent, care este nativ funcții, și dacă există o soluție mai bună.

Și chiar și atunci, că nu funcționează:

ME.find({$where: 'this.pictures.length > 0'}).sort('-created').limit(10).execFind()

Se întoarce nimic. Lăsând asta.imagini fără lungimea pic de lucru, dar apoi se întoarce, de asemenea, înregistrări goale, desigur.

440 2013-02-09T15:39:06+00:00 11
Neil Lunn
Neil Lunn
Întrebarea editată 30 octombrie 2017 в 8:51
Programare
mongodb
mongoose
Solution / Answer
 Chris'
Chris'
5 august 2014 в 3:24
2014-08-05T15:24:27+00:00
Mai mult
Sursă
Editează
#18464163

Dacă aveți, de asemenea, documente care don't au o cheie, puteți folosi:

ME.find({ pictures: { $exists: true, $not: {$size: 0} } })

MongoDB don't de a folosi indicii dacă $este implicat dimensiune, deci, aici este o soluție mai bună:

ME.find({ pictures: { $exists: true, $ne: [] } })

Deoarece MongoDB 2.6 eliberare, puteți compara cu operatorul $gt dar ar putea duce la rezultate neașteptate (puteți găsi un explicarea detaliata în acest răspuns):

ME.find({ pictures: { $gt: [] } })
 Chris'
Chris'
Răspuns editat 23 mai 2018 в 5:27
720
0
 skerit
skerit
9 februarie 2013 в 4:02
2013-02-09T16:02:48+00:00
Mai mult
Sursă
Editează
#18464161

După ce mai multe, mai ales în mongodb documente, și încurcat bits împreună, asta a fost raspunsul:

ME.find({pictures: {$exists: true, $not: {$size: 0}}})
 bgran
bgran
Răspuns editat 25 octombrie 2018 в 9:39
168
0
 tenbatsu
tenbatsu
16 iulie 2013 в 2:58
2013-07-16T02:58:52+00:00
Mai mult
Sursă
Editează
#18464162

Acest lucru ar putea lucra, de asemenea, pentru tine:

ME.find({'pictures.0': {$exists: true}});
Dan Dascalescu
Dan Dascalescu
Răspuns editat 8 iulie 2014 в 8:17
102
0
 wojcikstefan
wojcikstefan
4 martie 2017 в 8:49
2017-03-04T20:49:39+00:00
Mai mult
Sursă
Editează
#18464168

Ai grijă de două lucruri atunci când interogarea precizie și performanță. Cu asta în minte, am testat câteva abordări diferite în MongoDB v3.0.14.

TL;DR db.doc.find({ nums: { $gt: -Infinity }}) este cel mai rapid și cele mai fiabile (cel puțin în MongoDB versiune am testat).

EDIT: nu mai funcționează în MongoDB v3.6! A se vedea comentariile de sub acest post pentru o potențială soluție.

Setup

Am introdus 1k docs w/o o listă de teren, 1k docs cu o listă goală, și 5 documente cu un non-listă goală.

for (var i = 0; i < 1000; i++) { db.doc.insert({}); }
for (var i = 0; i < 1000; i++) { db.doc.insert({ nums: [] }); }
for (var i = 0; i < 5; i++) { db.doc.insert({ nums: [1, 2, 3] }); }
db.doc.createIndex({ nums: 1 });

Recunosc e't suficient de o scară pentru a avea o performanță la fel de serios ca eu sunt in testele de mai jos, dar's suficient de a prezenta corectitudinea diferite întrebări și comportamentul ales planurile de interogare.

Teste

db.doc.find({&#39;nums&#39;: {&#39;$există&#39;: true}}) returnează rezultate greșite (pentru ceea ce ne're încercarea de a realiza).

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': {'$exists': true}}).count()
1005

--

db.doc.find({&#39;nums.0&#39;: {&#39;$există&#39;: true}}) returnează rezultate corecte, dar's, de asemenea, lent, folosind o colecție completă de scanare (observa `COLLSCAN stadiul în explicația).

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': {'$exists': true}}).count()
5
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': {'$exists': true}}).explain()
{
  "queryPlanner": {
    "plannerVersion": 1,
    "namespace": "test.doc",
    "indexFilterSet": false,
    "parsedQuery": {
      "nums.0": {
        "$exists": true
      }
    },
    "winningPlan": {
      "stage": "COLLSCAN",
      "filter": {
        "nums.0": {
          "$exists": true
        }
      },
      "direction": "forward"
    },
    "rejectedPlans": [ ]
  },
  "serverInfo": {
    "host": "MacBook-Pro",
    "port": 27017,
    "version": "3.0.14",
    "gitVersion": "08352afcca24bfc145240a0fac9d28b978ab77f3"
  },
  "ok": 1
}

--

db.doc.find({&#39;num&#39;: { $există: adevărat, $gt: { &#39; dimensiune$&#39;: 0 }}}) returnează rezultate greșite. Ca's din cauza unui invalid index scan avansează niciun document. Acesta va fi probabil corecte, dar lent, fără index.

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $gt: { '$size': 0 }}}).count()
0
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $gt: { '$size': 0 }}}).explain('executionStats').executionStats.executionStages
{
  "stage": "KEEP_MUTATIONS",
  "nReturned": 0,
  "executionTimeMillisEstimate": 0,
  "works": 2,
  "advanced": 0,
  "needTime": 0,
  "needFetch": 0,
  "saveState": 0,
  "restoreState": 0,
  "isEOF": 1,
  "invalidates": 0,
  "inputStage": {
    "stage": "FETCH",
    "filter": {
      "$and": [
        {
          "nums": {
            "$gt": {
              "$size": 0
            }
          }
        },
        {
          "nums": {
            "$exists": true
          }
        }
      ]
    },
    "nReturned": 0,
    "executionTimeMillisEstimate": 0,
    "works": 1,
    "advanced": 0,
    "needTime": 0,
    "needFetch": 0,
    "saveState": 0,
    "restoreState": 0,
    "isEOF": 1,
    "invalidates": 0,
    "docsExamined": 0,
    "alreadyHasObj": 0,
    "inputStage": {
      "stage": "IXSCAN",
      "nReturned": 0,
      "executionTimeMillisEstimate": 0,
      "works": 1,
      "advanced": 0,
      "needTime": 0,
      "needFetch": 0,
      "saveState": 0,
      "restoreState": 0,
      "isEOF": 1,
      "invalidates": 0,
      "keyPattern": {
        "nums": 1
      },
      "indexName": "nums_1",
      "isMultiKey": true,
      "direction": "forward",
      "indexBounds": {
        "nums": [
          "({ $size: 0.0 }, [])"
        ]
      },
      "keysExamined": 0,
      "dupsTested": 0,
      "dupsDropped": 0,
      "seenInvalidated": 0,
      "matchTested": 0
    }
  }
}

--

db.doc.find({&#39;num&#39;: { $există: adevărat, $nu: { &#39; dimensiune$&#39;: 0 }}}) returnează rezultate corecte, dar performanta este rău. Din punct de vedere tehnic nu un index scan, dar apoi încă avansuri toate documentele și apoi trebuie să se filtrează printr-ele).

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $not: { '$size': 0 }}}).count()
5
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $not: { '$size': 0 }}}).explain('executionStats').executionStats.executionStages
{
  "stage": "KEEP_MUTATIONS",
  "nReturned": 5,
  "executionTimeMillisEstimate": 0,
  "works": 2016,
  "advanced": 5,
  "needTime": 2010,
  "needFetch": 0,
  "saveState": 15,
  "restoreState": 15,
  "isEOF": 1,
  "invalidates": 0,
  "inputStage": {
    "stage": "FETCH",
    "filter": {
      "$and": [
        {
          "nums": {
            "$exists": true
          }
        },
        {
          "$not": {
            "nums": {
              "$size": 0
            }
          }
        }
      ]
    },
    "nReturned": 5,
    "executionTimeMillisEstimate": 0,
    "works": 2016,
    "advanced": 5,
    "needTime": 2010,
    "needFetch": 0,
    "saveState": 15,
    "restoreState": 15,
    "isEOF": 1,
    "invalidates": 0,
    "docsExamined": 2005,
    "alreadyHasObj": 0,
    "inputStage": {
      "stage": "IXSCAN",
      "nReturned": 2005,
      "executionTimeMillisEstimate": 0,
      "works": 2015,
      "advanced": 2005,
      "needTime": 10,
      "needFetch": 0,
      "saveState": 15,
      "restoreState": 15,
      "isEOF": 1,
      "invalidates": 0,
      "keyPattern": {
        "nums": 1
      },
      "indexName": "nums_1",
      "isMultiKey": true,
      "direction": "forward",
      "indexBounds": {
        "nums": [
          "[MinKey, MaxKey]"
        ]
      },
      "keysExamined": 2015,
      "dupsTested": 2015,
      "dupsDropped": 10,
      "seenInvalidated": 0,
      "matchTested": 0
    }
  }
}

--

db.doc.find({&#39;num&#39;: { $există: adevărat, $ne: [] }}) returnează rezultate corecte și este puțin mai repede, dar performanța nu este încă ideală. Folosește IXSCAN care doar avansuri docs cu o listă existentă domeniu, dar apoi trebuie să filtreze gol listele unul câte unul.

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $ne: [] }}).count()
5
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $ne: [] }}).explain('executionStats').executionStats.executionStages
{
  "stage": "KEEP_MUTATIONS",
  "nReturned": 5,
  "executionTimeMillisEstimate": 0,
  "works": 1018,
  "advanced": 5,
  "needTime": 1011,
  "needFetch": 0,
  "saveState": 15,
  "restoreState": 15,
  "isEOF": 1,
  "invalidates": 0,
  "inputStage": {
    "stage": "FETCH",
    "filter": {
      "$and": [
        {
          "$not": {
            "nums": {
              "$eq": [ ]
            }
          }
        },
        {
          "nums": {
            "$exists": true
          }
        }
      ]
    },
    "nReturned": 5,
    "executionTimeMillisEstimate": 0,
    "works": 1017,
    "advanced": 5,
    "needTime": 1011,
    "needFetch": 0,
    "saveState": 15,
    "restoreState": 15,
    "isEOF": 1,
    "invalidates": 0,
    "docsExamined": 1005,
    "alreadyHasObj": 0,
    "inputStage": {
      "stage": "IXSCAN",
      "nReturned": 1005,
      "executionTimeMillisEstimate": 0,
      "works": 1016,
      "advanced": 1005,
      "needTime": 11,
      "needFetch": 0,
      "saveState": 15,
      "restoreState": 15,
      "isEOF": 1,
      "invalidates": 0,
      "keyPattern": {
        "nums": 1
      },
      "indexName": "nums_1",
      "isMultiKey": true,
      "direction": "forward",
      "indexBounds": {
        "nums": [
          "[MinKey, undefined)",
          "(undefined, [])",
          "([], MaxKey]"
        ]
      },
      "keysExamined": 1016,
      "dupsTested": 1015,
      "dupsDropped": 10,
      "seenInvalidated": 0,
      "matchTested": 0
    }
  }
}

--

db.doc.find({&#39;num&#39;: { $gt: [] }}) ESTE PERICULOS, DEOARECE ÎN FUNCȚIE de INDICELE FOLOSIT S-ar PUTEA DA REZULTATE NEAȘTEPTATE. Ca's din cauza unui invalid index scan care avansează niciun document.

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).count()
0
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).hint({ nums: 1 }).count()
0
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).hint({ _id: 1 }).count()
5

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).explain('executionStats').executionStats.executionStages
{
  "stage": "KEEP_MUTATIONS",
  "nReturned": 0,
  "executionTimeMillisEstimate": 0,
  "works": 1,
  "advanced": 0,
  "needTime": 0,
  "needFetch": 0,
  "saveState": 0,
  "restoreState": 0,
  "isEOF": 1,
  "invalidates": 0,
  "inputStage": {
    "stage": "FETCH",
    "filter": {
      "nums": {
        "$gt": [ ]
      }
    },
    "nReturned": 0,
    "executionTimeMillisEstimate": 0,
    "works": 1,
    "advanced": 0,
    "needTime": 0,
    "needFetch": 0,
    "saveState": 0,
    "restoreState": 0,
    "isEOF": 1,
    "invalidates": 0,
    "docsExamined": 0,
    "alreadyHasObj": 0,
    "inputStage": {
      "stage": "IXSCAN",
      "nReturned": 0,
      "executionTimeMillisEstimate": 0,
      "works": 1,
      "advanced": 0,
      "needTime": 0,
      "needFetch": 0,
      "saveState": 0,
      "restoreState": 0,
      "isEOF": 1,
      "invalidates": 0,
      "keyPattern": {
        "nums": 1
      },
      "indexName": "nums_1",
      "isMultiKey": true,
      "direction": "forward",
      "indexBounds": {
        "nums": [
          "([], BinData(0, ))"
        ]
      },
      "keysExamined": 0,
      "dupsTested": 0,
      "dupsDropped": 0,
      "seenInvalidated": 0,
      "matchTested": 0
    }
  }
}

--

db.doc.find({&#39;nums.0': { $gt: -Infinity }}) returnează rezultate corecte, dar are rău de performanță (folosește o colecție completă de scanare).

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': { $gt: -Infinity }}).count()
5
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': { $gt: -Infinity }}).explain('executionStats').executionStats.executionStages
{
  "stage": "COLLSCAN",
  "filter": {
    "nums.0": {
      "$gt": -Infinity
    }
  },
  "nReturned": 5,
  "executionTimeMillisEstimate": 0,
  "works": 2007,
  "advanced": 5,
  "needTime": 2001,
  "needFetch": 0,
  "saveState": 15,
  "restoreState": 15,
  "isEOF": 1,
  "invalidates": 0,
  "direction": "forward",
  "docsExamined": 2005
}

--

db.doc.find({&#39;num&#39;: { $gt: -Infinity }}) în mod surprinzător, acest lucru funcționează foarte bine! Acesta oferă dreptul de rezultatele și de a-l's rapid, avansarea 5 documente de scanare index fază.

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: -Infinity }}).explain('executionStats').executionStats.executionStages
{
  "stage": "FETCH",
  "nReturned": 5,
  "executionTimeMillisEstimate": 0,
  "works": 16,
  "advanced": 5,
  "needTime": 10,
  "needFetch": 0,
  "saveState": 0,
  "restoreState": 0,
  "isEOF": 1,
  "invalidates": 0,
  "docsExamined": 5,
  "alreadyHasObj": 0,
  "inputStage": {
    "stage": "IXSCAN",
    "nReturned": 5,
    "executionTimeMillisEstimate": 0,
    "works": 15,
    "advanced": 5,
    "needTime": 10,
    "needFetch": 0,
    "saveState": 0,
    "restoreState": 0,
    "isEOF": 1,
    "invalidates": 0,
    "keyPattern": {
      "nums": 1
    },
    "indexName": "nums_1",
    "isMultiKey": true,
    "direction": "forward",
    "indexBounds": {
      "nums": [
        "(-inf.0, inf.0]"
      ]
    },
    "keysExamined": 15,
    "dupsTested": 15,
    "dupsDropped": 10,
    "seenInvalidated": 0,
    "matchTested": 0
  }
}
 wojcikstefan
wojcikstefan
Răspuns editat 16 mai 2018 в 1:07
32
0
 JohnnyHK
JohnnyHK
6 februarie 2015 в 3:10
2015-02-06T15:10:19+00:00
Mai mult
Sursă
Editează
#18464164

Începând cu 2.6 presă, un alt mod de a face acest lucru este de a compara câmp la un array gol:

ME.find({pictures: {$gt: []}})

Testarea în coajă:

> db.ME.insert([
{pictures: [1,2,3]},
{pictures: []},
{pictures: ['']},
{pictures: [0]},
{pictures: 1},
{foobar: 1}
])

> db.ME.find({pictures: {$gt: []}})
{ "_id": ObjectId("54d4d9ff96340090b6c1c4a7"), "pictures": [ 1, 2, 3 ] }
{ "_id": ObjectId("54d4d9ff96340090b6c1c4a9"), "pictures": [ "" ] }
{ "_id": ObjectId("54d4d9ff96340090b6c1c4aa"), "pictures": [ 0 ] }

Deci, în mod corespunzător include docs unde "pictures" are cel puțin un element de matrice, și exclude docs unde "pictures" este fie un array gol, nu o matrice, sau lipsește.

 JohnnyHK
JohnnyHK
Răspuns editat 12 iunie 2015 в 12:34
28
0
Paul Imisi
Paul Imisi
15 iunie 2015 в 8:27
2015-06-15T08:27:04+00:00
Mai mult
Sursă
Editează
#18464166

Puteți utiliza oricare dintre următoarele pentru a realiza acest lucru. Ambele, de asemenea, grijă de a nu se întoarce un rezultat pentru obiecte care nu't au solicitat cheie în ele:

db.video.find({pictures: {$exists: true, $gt: {$size: 0}}})
db.video.find({comments: {$exists: true, $not: {$size: 0}}})
Quentin Hayot
Quentin Hayot
Răspuns editat 15 iunie 2015 в 8:53
5
0
Prabhat Yadav
Prabhat Yadav
28 februarie 2018 в 6:16
2018-02-28T06:16:51+00:00
Mai mult
Sursă
Editează
#18464169
{ $where: "this.pictures.length > 1" }

folosi $de unde și trece aceasta.nume_câmp.lungimea care returnează dimensiunea de matrice teren și verifică prin compararea cu numărul. dacă orice matrice au nici o valoare decât dimensiunea tabloului trebuie să fie de cel puțin 1. deci toate matrice domeniu au lungime mai mult de una, înseamnă că ai niște date în matrice

0
0
 SC1000
SC1000
23 septembrie 2018 в 11:51
2018-09-23T11:51:53+00:00
Mai mult
Sursă
Editează
#18464170

de a Prelua toate și numai în cazul în care documentele 'imagini' este o matrice și nu este gol

ME.find({pictures: {$type: 'array', $ne: []}})

Dacă utilizați un MongoDb versiune anterioară 3.2, folosi $tip: 4 "în loc de" $tip: &#39;matrice&#39;. Observați că această soluție nu't de a folosi chiar $size, deci nu's nici o problema cu indici ("Interogări se poate utiliza indicii pentru $dimensiunea porțiune dintr-o interogare")

Alte soluții, inclusiv aceste (răspunsul acceptat):

MINE.find({ imagini: { $există: adevărat, $nu: {$size: 0} } }); MINE.find({ imagini: { $există: adevărat, $ne: [] } })

sunt greșit pentru că se vor întoarce documentele, chiar dacă, de exemplu, 'imagini' se nul, nedefinit, 0, etc.

0
0
Andres Moreno
Andres Moreno
19 mai 2019 в 8:43
2019-05-19T20:43:46+00:00
Mai mult
Sursă
Editează
#18464171

Folosi $elemMatch operator: în conformitate cu documentația

$elemMatch operator meciuri documente care conțin o serie de teren, cu cel puțin un element care se potrivește toate specificate criteriile de interogare.

$elemMatches face-vă că valoarea este o matrice și că acesta nu este gol. Deci, interogarea ar fi ceva de genul

MĂ.find({ imagini: { $elemMatch: {$există: true }}})

PS O variantă a acestui cod se găsește în MongoDB Universitatea's M121 curs.

0
0
Eat  at Joes
Eat at Joes
10 februarie 2016 в 7:28
2016-02-10T19:28:01+00:00
Mai mult
Sursă
Editează
#18464167

De asemenea, puteți utiliza metoda de ajutor Există de-a lungul Mongo operator $există

ME.find()
    .exists('pictures')
    .where('pictures').ne([])
    .sort('-created')
    .limit(10)
    .exec(function(err, results){
        ...
    });
-1
0
Luis Fletes
Luis Fletes
9 februarie 2015 в 8:29
2015-02-09T20:29:28+00:00
Mai mult
Sursă
Editează
#18464165
ME.find({pictures: {$exists: true}}) 

Simplu, aceasta a lucrat pentru mine.

-7
0
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
Utilizatori
Toate
Nou
Populare
1
工藤 芳則
Înregistrat 6 zile în urmă
2
Ирина Беляева
Înregistrat 1 săptămână în urmă
3
Darya Arsenyeva
Înregistrat 1 săptămână în urmă
4
anyta nuam-nuam (LapuSiK)
Înregistrat 1 săptămână în urmă
5
Shuhratjon Imomkulov
Înregistrat 1 săptămână în urmă
DE
ES
FR
ID
JA
KO
NO
PT
RO
RU
TR
ZH
© kzen.dev 2023
Sursă
stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire