MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Rechercher des documents où un champ est comparable à un autre dans un tableau

Vous pouvez toujours utiliser aggregate() ici avec MongoDB 3.2, mais en utilisant simplement $redact à la place :

db.boards.aggregate([
  { "$redact": {
    "$cond": {
      "if": {
        "$and": [
          { "$ne": [ "$createdBy._id", "$owner._id" ] },
          { "$setIsSubset": [["$createdBy._id"], "$acl.profile._id"] }
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

Ou avec $where pour le shell MongoDB 3.2, il vous suffit de conserver une copie étendue de this , et votre syntaxe était un peu erronée :

db.boards.find({
  "$where": function() {
    var self = this;
    return (this.createdBy._id != this.owner._id)
      && this.acl.some(function(e) {
        return e.profile._id === self.createdBy._id
     })
  }
})

Ou alors dans un environnement compatible ES6 :

db.boards.find({
  "$where": function() {
    return (this.createdBy._id != this.owner._id)
      && this.acl.some(e => e.profile._id === this.createdBy._id)
  }
})

L'agrégat est l'option la plus performante des deux et doit toujours être préférable à l'utilisation de l'évaluation JavaScript

Et pour ce que ça vaut, la nouvelle syntaxe avec $expr serait :

db.boards.find({
  "$expr": {
    "$and": [
      { "$ne": [ "$createdBy._id", "$owner._id" ] },
      { "$in": [ "$createdBy._id", "$acl.profile._id"] }
    ]
  }
})

Utilisation de $in de préférence à $setIsSubset où la syntaxe est un peu plus courte.

    return (this.createdBy._id.valueOf() != this.owner._id.valueOf())
      && this.acl.some(e => e.profile._id.valueOf() === this.createdBy._id.valueOf())