java操作mongodb源码

时间:2025-02-12 08:29:35
/** *Query query = new Query(); * (("name").is(name)); * @param key * @return */ //把多个条件组合在一起 public static Criteria where(String key) { return new Criteria(key); } //封装查询条件 /**例如: * *创建匹配器,即如何使用查询条件 * ExampleMatcher matcher = () //构建对象 * .withStringMatcher() //改变默认字符串匹配方式:模糊查询 * .withIgnoreCase(true) //改变默认大小写忽略方式:忽略大小写 * .withMatcher("name", ()) //标题采用“包含匹配”的方式查询 * .withIgnorePaths("pageNum", "pageSize"); //忽略属性,不参与查询 *创建实例 *Example<Student> example = (student, matcher); *Query query = new Query((example)); **/ public static Criteria byExample(Object example) { return byExample(Example.of(example)); } //封装查询条件 public static Criteria byExample(Example<?> example) { return (new Criteria()).alike(example); } //匹配文档 public static Criteria matchingDocumentStructure(MongoJsonSchema schema) { return (new Criteria()).andDocumentStructureMatches(schema); } //并且 public Criteria and(String key) { return new Criteria(this.criteriaChain, key); } //是 public Criteria is(@Nullable Object o) { if (!this.isValue.equals(NOT_SET)) { throw new InvalidMongoDbApiUsageException("Multiple 'is' values declared. You need to use 'and' with multiple criteria"); } else if (this.lastOperatorWasNot()) { throw new InvalidMongoDbApiUsageException("Invalid query: 'not' can't be used with 'is' - use 'ne' instead."); } else { this.isValue = o; return this; } } //用于匹配正则表达式 private boolean lastOperatorWasNot() { return !this.criteria.isEmpty() && "$not".equals(this.criteria.keySet().toArray()[this.criteria.size() - 1]); } //不等于 public Criteria ne(@Nullable Object o) { this.criteria.put("$ne", o); return this; } //小于 public Criteria lt(Object o) { this.criteria.put("$lt", o); return this; } //小于等于 public Criteria lte(Object o) { this.criteria.put("$lte", o); return this; } //大于 public Criteria gt(Object o) { this.criteria.put("$gt", o); return this; } //大于等于 public Criteria gte(Object o) { this.criteria.put("$gte", o); return this; } //包含 public Criteria in(Object... o) { if (o.length > 1 && o[1] instanceof Collection) { throw new InvalidMongoDbApiUsageException("You can only pass in one argument of type " + o[1].getClass().getName()); } else { this.criteria.put("$in", Arrays.asList(o)); return this; } } //包含 public Criteria in(Collection<?> c) { this.criteria.put("$in", c); return this; } //与in相反 public Criteria nin(Object... o) { return this.nin((Collection)Arrays.asList(o)); } //与in相反 public Criteria nin(Collection<?> o) { this.criteria.put("$nin", o); return this; } //取模(求余)运算 ,即:key对应的值%value==remainder(求余是否等于remainder) public Criteria mod(Number value, Number remainder) { List<Object> l = new ArrayList(); l.add(value); l.add(remainder); this.criteria.put("$mod", l); return this; } //key键对应的集合包含col(all是包含关系,in是被包含关系) public Criteria all(Object... o) { return this.all((Collection)Arrays.asList(o)); } public Criteria all(Collection<?> o) { this.criteria.put("$all", o); return this; } //匹配key所对应的集合的元素的指定数量(!!!不能进行像<5之类的范围匹配) public Criteria size(int s) { this.criteria.put("$size", s); return this; } //查询字段是否存在(true:存在,false:不存在) public Criteria exists(boolean b) { this.criteria.put("$exists", b); return this; } //基于 bson type来匹配一个元素的类型,像是按照类型ID来匹配 public Criteria type(int t) { this.criteria.put("$type", t); return this; } public Criteria type(Type... types) { Assert.notNull(types, "Types must not be null!"); Assert.noNullElements(types, "Types must not contain null."); this.criteria.put("$type", Arrays.asList(types).stream().map(Type::value).collect(Collectors.toList())); return this; } //取反 public Criteria not() { return this.not((Object)null); } private Criteria not(@Nullable Object value) { this.criteria.put("$not", value); return this; } //模糊查询用 public Criteria regex(String re) { return this.regex(re, (String)null); } public Criteria regex(String re, @Nullable String options) { return this.regex(this.toPattern(re, options)); } public Criteria regex(Pattern pattern) { Assert.notNull(pattern, "Pattern must not be null!"); if (this.lastOperatorWasNot()) { return this.not(pattern); } else { this.isValue = pattern; return this; } } public Criteria regex(BsonRegularExpression regex) { if (this.lastOperatorWasNot()) { return this.not(regex); } else { this.isValue = regex; return this; } } // private Pattern toPattern(String regex, @Nullable String options) { Assert.notNull(regex, "Regex string must not be null!"); return Pattern.compile(regex, options == null ? 0 : BSON.regexFlags(options)); } public Criteria withinSphere(Circle circle) { Assert.notNull(circle, "Circle must not be null!"); this.criteria.put("$geoWithin", new GeoCommand(new Sphere(circle))); return this; } public Criteria within(Shape shape) { Assert.notNull(shape, "Shape must not be null!"); this.criteria.put("$geoWithin", new GeoCommand(shape)); return this; } //输出接近某一地理位置的有序文档 public Criteria near(Point point) { Assert.notNull(point, "Point must not be null!"); this.criteria.put("$near", point); return this; } //指定地理空间查询从最近到最远返回文档的点。 MongoDB 使用球面几何计算$nearSphere的距离 public Criteria nearSphere(Point point) { Assert.notNull(point, "Point must not be null!"); this.criteria.put("$nearSphere", point); return this; } // public Criteria intersects(GeoJson geoJson) { Assert.notNull(geoJson, "GeoJson must not be null!"); this.criteria.put("$geoIntersects", geoJson); return this; } //创建一个地理空间标准,与nearSphere一起使用 public Criteria maxDistance(double maxDistance) { if (!this.createNearCriteriaForCommand("$near", "$maxDistance", maxDistance) && !this.createNearCriteriaForCommand("$nearSphere", "$maxDistance", maxDistance)) { this.criteria.put("$maxDistance", maxDistance); return this; } else { return this; } } //mongodb地理空间计算逻辑 public Criteria minDistance(double minDistance) { if (!this.createNearCriteriaForCommand("$near", "$minDistance", minDistance) && !this.createNearCriteriaForCommand("$nearSphere", "$minDistance", minDistance)) { this.criteria.put("$minDistance", minDistance); return this; } else { return this; } } //匹配查询 public Criteria elemMatch(Criteria c) { this.criteria.put("$elemMatch", c.getCriteriaObject()); return this; } //使用给定对象作为模式创建条件 public Criteria alike(Example<?> sample) { this.criteria.put("$example", sample); this.criteriaChain.add(this); return this; } //创建一个criteria ($jsonSchema),根据MongoJsonSchema定义的给定结构匹配文档 public Criteria andDocumentStructureMatches(MongoJsonSchema schema) { Assert.notNull(schema, "Schema must not be null!"); Criteria schemaCriteria = new Criteria(); schemaCriteria.criteria.putAll(schema.toDocument()); return this.registerCriteriaChainElement(schemaCriteria); } public Criteria.BitwiseCriteriaOperators bits() { return new Criteria.BitwiseCriteriaOperatorsImpl(this); } //或者 /** * Aggregation agg = ( * (new Criteria() * .andOperator(("onlineTime").gt(new Date())) * .orOperator( ("offlineTime").gt(new Date()) * ,("offlineTime").exists(false) )) * @param criteria * @return */ public Criteria orOperator(Criteria... criteria) { BasicDBList bsonList = this.createCriteriaList(criteria); return this.registerCriteriaChainElement((new Criteria("$or")).is(bsonList)); } //非或者 public Criteria norOperator(Criteria... criteria) { BasicDBList bsonList = this.createCriteriaList(criteria); return this.registerCriteriaChainElement((new Criteria("$nor")).is(bsonList)); } //并且 public Criteria andOperator(Criteria... criteria) { BasicDBList bsonList = this.createCriteriaList(criteria); return this.registerCriteriaChainElement((new Criteria("$and")).is(bsonList)); } private Criteria registerCriteriaChainElement(Criteria criteria) { if (this.lastOperatorWasNot()) { throw new IllegalArgumentException("operator $not is not allowed around criteria chain element: " + criteria.getCriteriaObject()); } else { this.criteriaChain.add(criteria); return this; } } @Nullable public String getKey() { return this.key; } public Document getCriteriaObject() { if (this.criteriaChain.size() == 1) { return ((Criteria)this.criteriaChain.get(0)).getSingleCriteriaObject(); } else if (CollectionUtils.isEmpty(this.criteriaChain) && !CollectionUtils.isEmpty(this.criteria)) { return this.getSingleCriteriaObject(); } else { Document criteriaObject = new Document(); Iterator var2 = this.criteriaChain.iterator(); while(var2.hasNext()) { Criteria c = (Criteria)var2.next(); Document document = c.getSingleCriteriaObject(); Iterator var5 = document.keySet().iterator(); while(var5.hasNext()) { String k = (String)var5.next(); this.setValue(criteriaObject, k, document.get(k)); } } return criteriaObject; } } protected Document getSingleCriteriaObject() { Document document = new Document(); boolean not = false; Iterator var3 = this.criteria.entrySet().iterator(); while(true) { while(var3.hasNext()) { Entry<String, Object> entry = (Entry)var3.next(); String key = (String)entry.getKey(); Object value = entry.getValue(); if (requiresGeoJsonFormat(value)) { value = new Document("$geometry", value); } if (not) { Document notDocument = new Document(); notDocument.put(key, value); document.put("$not", notDocument); not = false; } else if ("$not".equals(key) && value == null) { not = true; } else { document.put(key, value); } } if (!StringUtils.hasText(this.key)) { if (not) { return new Document("$not", document); } return document; } Document queryCriteria = new Document(); if (!NOT_SET.equals(this.isValue)) { queryCriteria.put(this.key, this.isValue); queryCriteria.putAll(document); } else { queryCriteria.put(this.key, document); } return queryCriteria; } } private BasicDBList createCriteriaList(Criteria[] criteria) { BasicDBList bsonList = new BasicDBList(); Criteria[] var3 = criteria; int var4 = criteria.length; for(int var5 = 0; var5 < var4; ++var5) { Criteria c = var3[var5]; bsonList.add(c.getCriteriaObject()); } return bsonList; } private void setValue(Document document, String key, Object value) { Object existing = document.get(key); if (existing == null) { document.put(key, value); } else { throw new InvalidMongoDbApiUsageException("Due to limitations of the , you can't add a second '" + key + "' expression specified as '" + key + " : " + value + "'. Criteria already contains '" + key + " : " + existing + "'."); } } private boolean createNearCriteriaForCommand(String command, String operation, double maxDistance) { if (!this.criteria.containsKey(command)) { return false; } else { Object existingNearOperationValue = this.criteria.get(command); if (existingNearOperationValue instanceof Document) { ((Document)existingNearOperationValue).put(operation, maxDistance); return true; } else if (existingNearOperationValue instanceof GeoJson) { Document dbo = (new Document("$geometry", existingNearOperationValue)).append(operation, maxDistance); this.criteria.put(command, dbo); return true; } else { return false; } } } public boolean equals(Object obj) { if (this == obj) { return true; } else if (obj != null && this.getClass().equals(obj.getClass())) { Criteria that = (Criteria)obj; if (this.criteriaChain.size() != that.criteriaChain.size()) { return false; } else { for(int i = 0; i < this.criteriaChain.size(); ++i) { Criteria left = (Criteria)this.criteriaChain.get(i); Criteria right = (Criteria)that.criteriaChain.get(i); if (!this.simpleCriteriaEquals(left, right)) { return false; } } return true; } } else { return false; } } private boolean simpleCriteriaEquals(Criteria left, Criteria right) { boolean keyEqual = left.key == null ? right.key == null : left.key.equals(right.key); boolean criteriaEqual = left.criteria.equals(right.criteria); boolean valueEqual = this.isEqual(left.isValue, right.isValue); return keyEqual && criteriaEqual && valueEqual; } //判断是否相等 private boolean isEqual(Object left, Object right) { if (left == null) { return right == null; } else if (Pattern.class.isInstance(left)) { if (!Pattern.class.isInstance(right)) { return false; } else { Pattern leftPattern = (Pattern)left; Pattern rightPattern = (Pattern)right; return leftPattern.pattern().equals(rightPattern.pattern()) && leftPattern.flags() == rightPattern.flags(); } } else { return ObjectUtils.nullSafeEquals(left, right); } } public int hashCode() { int result = 17; int result = result + ObjectUtils.nullSafeHashCode(this.key); result += this.criteria.hashCode(); result += ObjectUtils.nullSafeHashCode(this.isValue); return result; } private static boolean requiresGeoJsonFormat(Object value) { return value instanceof GeoJson || value instanceof GeoCommand && ((GeoCommand)value).getShape() instanceof GeoJson; } private static class BitwiseCriteriaOperatorsImpl implements Criteria.BitwiseCriteriaOperators { private final Criteria target; BitwiseCriteriaOperatorsImpl(Criteria target) { this.target = target; } public Criteria allClear(int numericBitmask) { return this.numericBitmask("$bitsAllClear", numericBitmask); } public Criteria allClear(String bitmask) { return this.stringBitmask("$bitsAllClear", bitmask); } public Criteria allClear(List<Integer> positions) { return this.positions("$bitsAllClear", positions); } public Criteria allSet(int numericBitmask) { return this.numericBitmask("$bitsAllSet", numericBitmask); } public Criteria allSet(String bitmask) { return this.stringBitmask("$bitsAllSet", bitmask); } public Criteria allSet(List<Integer> positions) { return this.positions("$bitsAllSet", positions); } public Criteria anyClear(int numericBitmask) { return this.numericBitmask("$bitsAnyClear", numericBitmask); } public Criteria anyClear(String bitmask) { return this.stringBitmask("$bitsAnyClear", bitmask); } public Criteria anyClear(List<Integer> positions) { return this.positions("$bitsAnyClear", positions); } public Criteria anySet(int numericBitmask) { return this.numericBitmask("$bitsAnySet", numericBitmask); } public Criteria anySet(String bitmask) { return this.stringBitmask("$bitsAnySet", bitmask); } public Criteria anySet(List<Integer> positions) { return this.positions("$bitsAnySet", positions); } private Criteria positions(String operator, List<Integer> positions) { Assert.notNull(positions, "Positions must not be null!"); Assert.noNullElements(positions.toArray(), "Positions must not contain null values."); this.target.criteria.put(operator, positions); return this.target; } private Criteria stringBitmask(String operator, String bitmask) { Assert.hasText(bitmask, "Bitmask must not be null!"); this.target.criteria.put(operator, new Binary(Base64Utils.decodeFromString(bitmask))); return this.target; } private Criteria numericBitmask(String operator, int bitmask) { this.target.criteria.put(operator, bitmask); return this.target; } } public interface BitwiseCriteriaOperators { Criteria allClear(int var1); Criteria allClear(String var1); Criteria allClear(List<Integer> var1); Criteria allSet(int var1); Criteria allSet(String var1); Criteria allSet(List<Integer> var1); Criteria anyClear(int var1); Criteria anyClear(String var1); Criteria anyClear(List<Integer> var1); Criteria anySet(int var1); Criteria anySet(String var1); Criteria anySet(List<Integer> var1); } } }