sql >> Databasteknik >  >> NoSQL >> MongoDB

Hitta det första elementet i kapslad array som matchar villkoren

Bäst förmodligen att söka med $where utöver den normala frågan, och fortfarande ha saker på servern:

db.getCollection('collection').find({
  "array": {
    "$elemMatch": { "field": "BCD", "enabled": "true" },
  },
  "$where": function() {
    return this.array.map((e,i) => Object.assign(e,{ i }))
      .filter( e => e.field === "BCD" && e.enabled === "true" )
      .map( e => e.i )[0] <=
    this.array.map(e => e.enabled).indexOf("true")
  }  
})

Och om du har MongoDB 3.4 med stöd för $indexOfArray och $range , då kan det se längre ut men det är faktiskt mest effektivt med $ redigera :

db.getCollection('collection').aggregate([
  { "$match": {
    "array": {
      "$elemMatch": { "field": "BCD", "enabled": "true" },
    }
  }},
  { "$redact": {
    "$cond": {  
      "if": {
        "$lte": [
          { "$arrayElemAt": [
            { "$map": {
              "input": {
                "$filter": {
                  "input": {
                    "$map": {
                      "input": {
                        "$zip": {
                          "inputs": [
                            "$array",
                            { "$range": [0, { "$size": "$array" }] }
                          ]
                        }    
                      },
                      "as": "a",
                      "in": {
                        "field": { "$arrayElemAt": [ "$$a.field", 0 ] },
                        "enabled": { "$arrayElemAt": [ "$$a.enabled", 0 ] },
                        "index": { "$arrayElemAt": [ "$$a", 1 ] }    
                      }
                    }
                  },
                  "as": "a",
                  "cond": {
                    "$and": [
                      { "$eq": [ "$$a.field", "BCD" ] },
                      { "$eq": [ "$$a.enabled", "true" ] }
                    ]
                  }    
                }
              },
              "as": "a",
              "in": "$$a.index"  
            }},
            0
          ]},
          { "$indexOfArray": [ "$array.enabled", "true" ] } 
        ] 
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

Så det finns egentligen ingen faktisk frågeoperation som upprätthåller det, men båda dessa fall behåller valet "på servern" i motsats till att skicka data över tråden till klienten och sedan filtrera.

För om du gör det förnekar det liksom syftet med att använda en databas i första hand. Så du vill verkligen att detta ska hända på servern.



  1. Hur kan jag använda mongodump för att dumpa poster som matchar ett specifikt datumintervall?

  2. Hur man konverterar casbah mongodb list till json i scala / play

  3. Spring Data Mongo Query för att fråga med flera fält och returnera i ett samtal

  4. Hur ändrar man ordning på array med MongoDB?