2016-08-05 9 views
3

Ich habe Sammlung path_test mit 2 Dokumenten in ihmFinden Dokument mit Array, das ausschließlich bestimmte Dokumente in MongoDB

Dokument 1

{ 
    "_id" : 1, 
    "tpc" : 5, 
    "path" : [ 
    { 
     "nids" : [ 0, 10, 11 ], 
     "ctc" : 2 
    }, 
    { 
     "nids" : [ 0, 10 ], 
     "ctc" : 2 
    }, 
    { 
     "nids" : [ 0, 10, 21 ], 
     "ctc" : 1 
    } 
    ] 
} 

Dokument 2

{ 
    "_id" : 2, 
    "tpc" : 5, 
    "path" : [ 
    { 
     "nids" : [ 0, 10, 110 ], 
     "ctc" : 1 
    }, 
    { 
     "nids" : [ 0, 10, 11 ], 
     "ctc" : 2 
    }, 
    { 
     "nids" : [ 0, 5 ], 
     "ctc" : 2 
    } 
    ] 
} 

besteht Was Ich versuche, als Ergebnis Dokumente mitzu bekommenArray, in dem alle Elemente nids wie [0, 10, *] haben. Reihenfolge ist wichtig, also [10, 0, *] wird falsch sein. Es sollte Dokument 1, aber nicht Dokument 2 finden. Ich hoffe, ich kann dies mit einer Abfrage lösen, bevor ich Map-Reduce oder Aggregation verwende.

Dies ist, was ich

db.getCollection('path_test').find({ 
    "path": { $not: { $elemMatch: { "nids.0": { $nin: [0] }, "nids.1": { $nin: [10] } } } } 
}); 

Abfrage 2

db.getCollection('path_test').find({ 
    "path.nids": { $not: { $elemMatch: { $nin: [0, 10] } } } 
}); 

bisher

Query1 versucht haben, aber beide Abfragen geben Sie mir führt, wo nur 0 in oder wo nur 10 ist, aber ich brauche beide und in dieser genauen Reihenfolge.

Ist das möglich?

+1

Hoffe, dass Sie sich dessen bewusst sind. '$ ElemMatch' nur zurückkehren ein Datensatz, der der Abfrage entspricht – Shrabanee

+1

@Shrabanee Danke, dass du das herausgibst, aber ich habe verstanden, dass es mindestens ein Element mit diesem Feld enthält – adpap

+0

@Shrabanee https://docs.mongodb.com/manual/reference/operator/ query/elemMatch/ – adpap

Antwort

2

nicht mindestens ein Mittel noone

Abfrage 1

Zur Vereinfachung zuordnen lässt

A = "nids.0": { $ne: 0 } 
B = "nids.1": { $ne: 10 } 
C = { A, B } 

dann

{ "path" : { $elemMatch: C } } 

werden die Dokumente finden, wo mindestens ein Element in Array path Bedingung erfüllt C, während

{ "path" : { $not: { $elemMatch: C } } } 

Dokumente finden, wo es kein Element in path Array, das C Bedingung erfüllt.

Dokument 1 und Dokument 2 enthalten keine Elemente in ihren Arrays path, die die Bedingung C erfüllen, daher enthält die Ausgabe von Query1 beide. Wenn f.e Sie sich mit dem path Array des Dokuments hinzufügen 1

{ "nids": [ 1, 11, 110], "ctc" : 1 } 

dann 1 Dokument wird nicht in der Ausgabe von Abfrage seine 1 becase dieses zusätzlichen Element erfüllt C.

Abfrage 2

Zur Vereinfachung können

zuweisen
C = { $nin: [0, 10] } 

dann

{ "path.nids" : { $not: { $elemMatch: C } } } 

findet Dokumente, in denen es kein Element in path.nids Array, das C Bedingung erfüllt.

Dokument 1 und Dokument 2 in ihren path.nids Arrays haben Elemente, die die Bedingung C erfüllen, daher enthält die Ausgabe von Abfrage 2 keine von beiden. Wenn f.e, fügen Sie Sie Sammlung Dokument

{ "_id" : 6, "tpc" : 5, "path" : [ { "nids" : [ 0, 10 ], "ctc" : 1 } ] } 

dann wird es in der Ausgabe von Query-2 sein, da in path.nids Array keine Elemente, die C erfüllen.

Lösung

In Abfrage 1

{ $elemMatch: { "nids.0": { $nin: [0] }, "nids.1": { $nin: [10] } } } 

mit

{ $elemMatch: { $or: [ { "nids.0": { $ne: 0 } }, { "nids.1": { $ne: 10 } } ] } } 

Diese neuen Abfrage findet Dokumente ersetzen, wo es kein Element in path Array, das eine zumindest erfüllt von Bedingungen A und B. So wird es Dokument finden 1, jedoch nicht mehr als 2 Dokument (wo "nids" : [ 0, 5 ] nicht Bedingung nicht erfüllt B.

Beachten Sie, dass { $ne: 10 } zu { $nin: [10] } entspricht.

Verwandte Themen