docs: public static void check(final String repositoryName, final JSONObject jsonObject, final String... ignoredKeys)
              throws RepositoryException {
          if (null == jsonObject) {
              throw new RepositoryException("Null to persist to repository [" + repositoryName + "]");
          }
  
          final JSONObject repositoryDef = getRepositoryDef(repositoryName);
          if (!repositoryDef.optBoolean("fieldcheck")) { // 默认不启用字段检查 https://github.com/b3log/latke/issues/103
              return;
          }
  
          final boolean needIgnoreKeys = null != ignoredKeys && 0 < ignoredKeys.length;
          final JSONArray names = jsonObject.names();
          final Set<Object> nameSet = CollectionUtils.jsonArrayToSet(names);
  
          final JSONArray keysDef = repositoryDef.optJSONArray("keys");
          if (null == keysDef) {
              return;
          }
  
          final Set<String> keySet = new HashSet<>();
  
          // Checks whether the specified json object has all keys defined, and whether the type of its value is appropriate
          for (int i = 0; i < keysDef.length(); i++) {
              final JSONObject keyDescription = keysDef.optJSONObject(i);
  
              final String key = keyDescription.optString("name");
              keySet.add(key);
  
              if (needIgnoreKeys && Strings.containsIgnoreCase(key, ignoredKeys)) {
                  continue;
              }
  
              if (!keyDescription.optBoolean("nullable") && !nameSet.contains(key)) {
                  throw new RepositoryException("A json object to persist to repository [name=" + repositoryName + "] does not contain a key [" + key + "]");
              }
  
              // TODO: 88250, type and length validation
              /*
               * final String type = keyDescription.optString("type"); final
               * Object value = jsonObject.opt(key);
               *
               * if (("String".equals(type) && !(value instanceof String)) ||
               * ("int".equals(type) && !(value instanceof Integer)) ||
               * ("long".equals(type) && !(value instanceof Long)) ||
               * ("double".equals(type) && !(value instanceof Double)) ||
               * ("boolean".equals(type) && !(value instanceof Boolean))) {
               * LOGGER.log(Level.WARNING,
               * "A json object to persist to repository[name={0}] has " +
               * "a wrong value type[definedType={1}, currentType={2}] with key["
               * + key + "]", new Object[]{repositoryName, type,
               * value.getClass()});
               *
               * return true; }
               */
          }
  
          // Checks whether the specified json object has an redundant (undefined) key
          for (int i = 0; i < names.length(); i++) {
              final String name = names.optString(i);
              if (!keySet.contains(name)) {
                  throw new RepositoryException("A json object to persist to repository [name=" + repositoryName + "] contains an redundant key [" + name + "]");
              }
          }
      }