赞
踩
由于最近项目赶
,版本迭代快
,不知道大BOSS从哪里听别人说MongoDB用来做关系型数据库好,而且速度快,性能高;听到这话的我,立马就反驳了回去:“MongoDB不支持事物”!
结果查阅了大量资料,反被大BOSS啪啪打脸…,哎…,最终还是本着为大BOSS服务和学习的态度,技术选型上,关系型数据库由MySQL
转变成为MongoDB-4.2
;
由于一时半会儿还不太适应MongoDB的一些写法,查阅了大量的资料才搞定MongoDB在java中的实现方式,此次运用到的是spring的一个插件spring-data-mongodb
,版本号:2.2.6.RELEASE
;
mongodb-3.4.0
及以上<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
两张表关联查询,带多条件查询,分页,排序
传统的MongoDB的SQL语句实现
,如下:
db.shop.aggregate([ { "$lookup":{ "from":"member", // 从表表名 "localField":"userId", // 如shop被查询主表的userId,相对于member表的外键 "foreignField":"_id", // 如member从表的主键_id,相对于member表的主键 "as":"docs_member" // 联合查询出的别名,用于多条件查询表明前缀,相当于SQL中的临时表名 } }, { "$match":{ "shopStatus":1, "blockade":{ // in包含查询 "$in":[ 0, null ] }, "dataFlag":1 } }, { "$skip":{ "$numberLong":"0" } }, { "$limit":{ "$numberLong":"10" } }, { "$sort":{ "modifyTime":-1 } } ])
Java中实现以上写法,如下:
package /**这里是包名**/; import com.sszh.mall.shop.entity.ShopDO; import org.bson.types.ObjectId; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.stereotype.Repository; import java.util.List; import java.util.regex.Pattern; import org.springframework.data.mongodb.core.MongoTemplate; public class ShopServiceImpl { @Autowired protected MongoTemplate mongoTemplate; // 一对一:两表关联查询 private List<ShopDO> twoTableQuery(String keyword, int pageNum, int pageSize) { // TODO 店长是否实名认证 // 构建 Aggregation:添加查询条件 Aggregation aggregation = Aggregation.newAggregation( // 关联member表 Aggregation.lookup( "member", // 从表表名 "userId", // 如shop被查询主表的userId,相对于member表的外键 "_id", // 如member从表的主键_id,相对于member表的主键 "docs_member" // 联合查询出的别名,用于多条件查询表明前缀,相当于SQL中的临时表名 ), // ============================================= 以上内容可举一反三 ============================================= // 查询条件 null == keyword || "".equals(keyword.trim()) ? Aggregation.match( Criteria.where("shopStatus").is(1) // 店铺状态: 1:已审核 .and("blockade").in(0, null) // 店铺是否有效: 0=解封 -1=封锁 .and("dataFlag").is(1) // 店铺是否有效: 1:有效 .and("docs_member.telephone").is("8615323710096") // 添加member表查询条件,如用户手机号,此处可举一反三 ) : Aggregation.match( Criteria.where("shopStatus").is(1) .and("blockade").in(0, null) .and("dataFlag").is(1) // 根据店铺名称模糊搜索 .andOperator(Criteria.where("shopName").regex(Pattern.compile(keyword, Pattern.CASE_INSENSITIVE))) ), // 分页:页码 Aggregation.skip(Long.valueOf(pageNum)), // 分页:条数 Aggregation.limit((long) pageSize), // 排序 Aggregation.sort(Sort.Direction.DESC,"modifyTime") ); // 执行查询,这里的shop必须是查询的主表名 AggregationResults<ShopDO> results = mongoTemplate.aggregate(aggregation, "shop", ShopDO.class); return results.getMappedResults(); }
一对多关联查询(商品表为主表、取商品规格集合
):
db.mall_goods.aggregate([
{
$lookup:
{
from: "mall_specs",
localField: "id",
foreignField: "goods_id",
as: "inventory_docs"
}
}
]);
一对多关联查询(订单表为主表,根据商品ID取商品名称、商品规格集合
):
db.mall_order.aggregate([ { $lookup: { from: "mall_goods", localField: "id", foreignField: "goods_id", as: "goods" } }, { $lookup: { from: "mall_specs", localField: "goods_id", foreignField: "goods_id", as: "specs" } } ])
排序:根据商品【销售量 + 虚拟交易量】之和,进行倒叙排序(DESC):-1 降序 1 升序; 再根据价格,由小到大排序
传统的MongoDB的SQL语句实现
,如下:
db.product.aggregate([ { $project: { _id : 1, // ---------------- 部分代码省略 ---------------- shopId: 1, "saleNumCount" : { $sum: ["$saleNum", "$salesVolumeNum"] } } }, { $sort: {"saleNumCount" : -1}, $sort: {"price" : 1} } // ---------------- 分页代码省略(注意:这整块SQL语句都有先后顺序要求) ---------------- ])
备注:
Java中实现以上写法,如下:
package /*包名省略*/ import com.alibaba.fastjson.JSONObject; import com.mongodb.BasicDBObject; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.sszh.common.core.MongoOperator; import com.sszh.mall.product.entity.ProductDO; /*这个是返回的实体对象,不指定也可以*/ import com.sszh.mall.product.repository.ProductRepository; import com.sszh.mall.shop.entity.ShopDO; import com.sszh.mongodb.springdata.BaseMongoRepository; import com.sszh.utils.DateUtil; import com.sszh.utils.StringUtils; import org.bson.Document; import org.bson.types.ObjectId; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Repository; import java.math.BigDecimal; import java.util.*; public class ProductRepositoryImpl implements ProductRepository { @Autowired protected MongoTemplate mongoTemplate; public MongoTemplate getDatastore(){ return mongoTemplate; } @Override public List<ProductDO> getProductListByWhere(int categoryId,int pageNum,int pageSize) { List<Document> pipeline = new ArrayList<>(); // 设置返回指定字段,1 返回 0/不指定 不返回 Document basicDBObject = new Document(); basicDBObject.put("_id", 1); basicDBObject.put("shopId", 1); basicDBObject.put("categoryId", 1); basicDBObject.put("shieldSearch", 1); basicDBObject.put("productName", 1); basicDBObject.put("productPic", 1); basicDBObject.put("price", 1); basicDBObject.put("fare", 1); basicDBObject.put("profit", 1); basicDBObject.put("warnStock", 1); basicDBObject.put("productStock", 1); basicDBObject.put("isSale", 1); basicDBObject.put("isBest", 1); basicDBObject.put("productDescTitle", 1); basicDBObject.put("productDescEnd", 1); basicDBObject.put("saleNum", 1); basicDBObject.put("saleTime", 1); basicDBObject.put("dataFlag", 1); basicDBObject.put("praiseNum", 1); basicDBObject.put("forwardNum", 1); basicDBObject.put("attributes", 1); basicDBObject.put("forwardCommission", 1); basicDBObject.put("createTime", 1); basicDBObject.put("modifyTime", 1); basicDBObject.put("salesVolumeNum", 1); // 计算 【虚拟交易量 + 交易量】之和,返回字段 saleNumCount basicDBObject.put("saleNumCount", new BasicDBObject("$sum", Arrays.asList("$saleNum", "$salesVolumeNum"))); Document project = new Document(MongoOperator.PROJECT, basicDBObject); pipeline.add(project); // 排序:根据商品【销售量 + 虚拟交易量】之和,进行倒叙排序(DESC):-1 降序 1 升序; 再根据价格,由小到大排序 basicDBObject = new Document(); basicDBObject.put("saleNumCount", -1); basicDBObject.put("price", 1); Document sort = new Document(MongoOperator.SORT, basicDBObject); pipeline.add(sort); // 查询条件 basicDBObject = new Document(); basicDBObject.put("isSale", 1); //查询条件,状态是否可用 basicDBObject.put("dataFlag", new BasicDBObject(MongoOperator.NE, -1)); //商品是否被删除 basicDBObject.put("shieldSearch", new BasicDBObject(MongoOperator.NE, 1)); //商品是否可以搜索 Document match = new Document(MongoOperator.MATCH, basicDBObject); //将查询条件添加到match中 pipeline.add(match); // 分页:开始位置 Document skip = new Document(MongoOperator.SKIP, (pageNum * pageSize)); pipeline.add(skip); // 分页:结束位置 Document limit = new Document(MongoOperator.LIMIT, ((pageNum + 1) * pageSize)); pipeline.add(limit); // 执行聚合查询操作:获取数据库连接、指定表名:product,发回结果集:cursor final MongoCursor<Document> cursor = getDatastore().getCollection("product").aggregate(pipeline).iterator(); // 处理结果集 List<ProductDO> list = new ArrayList<>(); ProductDO productDO; while (cursor.hasNext()) { Document dbObject = cursor.next(); productDO = JSONObject.toJavaObject(JSONObject.parseObject(JSONObject.toJSONString(dbObject)), ProductDO.class); productDO.setId((ObjectId)dbObject.get("_id")); list.add(productDO); } return list; } }
mongodb 关键词常量类:
package com.sszh.common.core; public final class MongoOperator { // id public static final String ID = "_id"; // query condition public static final String GT = "$gt"; public static final String GTE = "$gte"; public static final String LT = "$lt"; public static final String LTE = "$lte"; public static final String NE = "$ne"; public static final String IN = "$in"; public static final String NIN = "$nin"; public static final String MOD = "$mod"; public static final String ALL = "$all"; public static final String SLICE = "$slice"; public static final String SIZE = "$size"; public static final String EXISTS = "$exists"; public static final String WHERE = "$where"; public static final String REGEX ="$regex"; // query logic public static final String AND = "$and"; public static final String OR = "$or"; // 2d and geo public static final String NEAR = "$near"; public static final String WITHIN = "$within"; public static final String CENTER = "$center"; public static final String BOX = "$box"; // update public static final String SET = "$set"; public static final String UNSET = "$unset"; public static final String INC = "$inc"; public static final String MUL = "$mul"; public static final String PUSH = "$push"; public static final String PULL = "$pull"; public static final String EACH = "$each"; public static final String POP = "$pop"; public static final String MIN = "$min"; public static final String MAX = "$max"; public static final String BIT = "$bit"; // aggregation public static final String PROJECT = "$project"; public static final String MATCH = "$match"; public static final String LIMIT = "$limit"; public static final String SKIP = "$skip"; public static final String UNWIND = "$unwind"; public static final String GROUP = "$group"; public static final String SORT = "$sort"; }
参考文献:
spring-data-mongodb官方参考文档:
https://docs.spring.io/spring-data/mongodb/docs/3.0.0.RELEASE/reference/html/#mongodb.repositories.queries.aggregation
mongoTemplate.aggregate() 聚合查询,关联查询:
https://blog.csdn.net/C18298182575/article/details/100698885
使用spring-data-mongodb对mongo进行联表分页查询:
https://blog.csdn.net/qazwsx081/article/details/97897187
Spring Data Mongodb多表关联查询:
https://blog.csdn.net/zhang135123/article/details/85273957
SpringBoot整合MongoDB实现聚合查询(多表联查)以及一套简单CRUD:
https://blog.csdn.net/weixin_44530530/article/details/91901631
MongoDB的多表关联查询:
https://blog.csdn.net/watersprite_ct/article/details/78500997
Spring Data Mongodb多表关联查询:
https://blog.csdn.net/zhang135123/article/details/85273957
Java使用mongodb进行数据存储及多表关联,多条件查询:
https://blog.csdn.net/lchq1995/article/details/102586243
Spring Data MongoDB-参考文档:
https://docs.spring.io/spring-data/mongodb/docs/2.2.3.RELEASE/reference/html/#mapping-usage
注:以上内容仅提供参考和交流,请勿用于商业用途,如有侵权联系本人删除!
如有对思路不清晰或有更好的解决思路,欢迎与本人交流,微信:seesun2012(非紧急项目请加QQ群解答
),QQ群:273557553
你遇到的问题是小编创作灵感的来源!
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。