sql >> データベース >  >> NoSQL >> MongoDB

クエリビルダーの条件を、サブドキュメントのネストされた配列を含むMongoDB操作に変換します

    さらに調査した後、私は実用的な解決策を手に入れました。洞察を提供してくれたすべての有益なレスポンダーに感謝します。

    この関数は、Angularクエリビルダーモジュールからクエリを取得し、それをMongoDBクエリに変換します。

    Angularクエリビルダー

      {
        "condition": "and",
        "rules": [{
          "field": "RecordType",
          "operator": "=",
          "value": "Item"
        }, {
          "condition": "or",
          "rules": [{
            "field": "Items.Title",
            "operator": "contains",
            "value": "book"
          }, {
            "field": "Project",
            "operator": "in",
            "value": ["5d0699380a2958e44503acfb", "5d0699380a2958e44503ad2a", "5d0699380a2958e44503ad18"]
          }]
        }]
      }
    

    MongoDBクエリ結果

      {
        "$and": [{
          "RecordType": {
            "$eq": "Item"
          }
        }, {
          "$or": [{
            "Items.Title": {
              "$regex": "book",
              "$options": "i"
            }
          }, {
            "Project": {
              "$in": ["5d0699380a2958e44503acfb", "5d0699380a2958e44503ad2a", "5d0699380a2958e44503ad18"]
            }
          }]
        }]
      }
    

    コード

    /**
     * Convert a query object generated by UI to MongoDB query
     * @param query a query builder object generated by Angular2QueryBuilder module
     * @param model the model for the schema to query
     * return a MongoDB query
     * 
     */
    
    apiCtrl.convertQuery = async (query, model) => {
    
      if (!query || !model) {
        return {};
      }
    
      const conditions = { "and": "$and", "or": "$or" };
      const operators = {
        "=": "$eq",
        "!=": "$ne",
        "<": "$lt",
        "<=": "$lte",
        ">": "$gt",
        ">=": "gte",
        "in": "$in",
        "not in": "$nin",
        "contains": "$regex"
      };
    
      // Get Mongoose schema type instance of a field
      const getSchemaType = (field) => {
        return model.schema.paths[field] ? model.schema.paths[field].instance : false;
      }
    
      // Map each rule to a MongoDB query
      const mapRule = (rule) => {
    
        let field = rule.field;
        let value = rule.value;
    
        if (!value) {
          value = null;
        }
    
        // Get schema type of current field
        const schemaType = getSchemaType(rule.field);
    
        // Check if schema type of current field is ObjectId
        if (schemaType === 'ObjectID' && value) {
          // Convert string value to MongoDB ObjectId
          if (Array.isArray(value)) {
            value.map(val => new ObjectId(val));
          } else {
            value = new ObjectId(value);
          }
        // Check if schema type of current field is Date
        } else if (schemaType === 'Date' && value) {
          // Convert string value to ISO date
          console.log(value);
          value = new Date(value);
        }
    
        console.log(schemaType);
        console.log(value);
    
        // Set operator
        const operator = operators[rule.operator] ? operators[rule.operator] : '$eq';
    
        // Create a MongoDB query
        let mongoDBQuery;
    
        // Check if operator is $regex
        if (operator === '$regex') {
          // Set case insensitive option
          mongoDBQuery = {
            [field]: {
              [operator]: value,
              '$options': 'i'
            }
          };
        } else {
          mongoDBQuery = { [field]: { [operator]: value } };
        }
    
        return mongoDBQuery;
    
      }
    
      const mapRuleSet = (ruleSet) => {
    
        if (ruleSet.rules.length < 1) {
          return;
        }
    
        // Iterate Rule Set conditions recursively to build database query
        return {
          [conditions[ruleSet.condition]]: ruleSet.rules.map(
            rule => rule.operator ? mapRule(rule) : mapRuleSet(rule)
          )
        }
      };
    
      let mongoDbQuery = mapRuleSet(query);
    
      return mongoDbQuery;
    
    }
    



    1. MongoDBObjectIdsの公開

    2. Meteor-MongoDBエラー:$addToSet修飾子を非配列に適用できません

    3. Mongoで欠落している日付を含むGroupByAggregation

    4. DoctrineMongoDBはidで検索します