Java实现对MongoDB的两表关联查询(jdk1.7),$lookup

参考:

聚合框架 

聚合框架是MongoDB的高级查询语言,它允许我们通过转换和合并多个文档中的数据来生成新的单个文档中不存在的信息。

聚合管道操作主要包含下面几个部分:

命令功能描述
$project指定输出文档里的字段.
$match选择要处理的文档,与fine()类似。
$limit限制传递给下一步的文档数量。
$skip跳过一定数量的文档。
$unwind扩展数组,为每个数组入口生成一个输出文档。
$group根据key来分组文档。
$sort排序文档。
$geoNear选择某个地理位置附近的的文档。
$out把管道的结果写入某个集合。
$redact控制特定数据的访问。

$lookup

多表关联(3.2版本新增)

MongoDB查询(工具:Robo 3T): 

// 两个集合关联查询
// 小表(HTQH_BROKER_CUST_RELA)做主表
db.getCollection('HTQH_BROKER_CUST_RELA').aggregate([    
    // 主表的查询条件
    {$match: {'BROKER_NUM': {$in: ['DA1831']}}},
    {
        $lookup: {
            // 大表(D01_CUST_LABEL)做从表
            from: 'D01_CUST_LABEL', 
            localField: 'CUST_NUM',  // 主表字段
            foreignField: 'CUST_NUM',  // 子表字段
            as: 'BROKER_CUST'  // 别名
        }
    }, 
    // 关联后的查询条件
    {$match: {
        // 查询满足条件(LABL_GRP='sex_cd',且LABL_ID in ['1', '2'])或条件(LABL_GRP='cust_type_cd',且LABL_ID in ['100', '102'])的所有数据
        $or: [
            // 查询从表数据,需要用别名.从表的字段名
            {$and: [{'BROKER_CUST.LABL_GRP': 'sex_cd', 'BROKER_CUST.LABL_ID': {$in: ['1', '2']}}]}, 
            {$and: [{'BROKER_CUST.LABL_GRP': 'cust_type_cd', 'BROKER_CUST.LABL_ID': {$in: ['100', '102']}}]}
        ]
    }},
    // 查询结果只显示CUST_NUM列,_id需手动隐藏
//    {$project: {CUST_NUM: 1, _id: 0}}, 
    // 统计总条数
    {$group: {_id: 'Total', count: {$sum: 1}}}, 
    // 按CUST_NUM分组,并统计每个CUST_NUM出现的次数
//    {$group: {_id: '$CUST_NUM', count: {$sum: 1}}}, 
]);

Java:


<dependency>
	<groupId>org.mongodb</groupId>
	<artifactId>mongodb-driver</artifactId>
	<version>3.2.2</version>
</dependency>
<dependency>
	<groupId>com.google.code.gson</groupId>
	<artifactId>gson</artifactId>
	<version>2.3.1</version>
</dependency>
<!-- 因为是jdk1.7所以用的低版本的jar -->
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-mongodb</artifactId>
	<version>1.5.4.RELEASE</version>
</dependency>
import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Aggregates;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Sorts;

public class demo {
	// DataRow是一个HashMap
	
	private List<String> queryCustNum(String broker_nums, 
			String labl_thme_id, String labl_grp_clas_id, String labl_grp, 
			String[] label_id, List<String> custNums) throws TKMongoException {
		long beginTime = System.currentTimeMillis();

		// 连接MongoDB无密码
//		MongoClient client = new MongoClient("l27.0.0.1", 27017);
//		MongoDatabase mongoDatabase = client.getDatabase("databaseName");
		
		// 连接MongoDB有密码
		ServerAddress serverAddress = new ServerAddress("l27.0.0.1", 27017);
		List<ServerAddress> addrs = new ArrayList<>();
		addrs.add(serverAddress);
		// 三个参数分别为:用户名、数据库名称、密码
		MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());
		List<MongoCredential> credentials = new ArrayList<>();
		credentials.add(credential);
		
		// 通过连接认证获取MongoDB连接
		MongoClient client = new MongoClient(addrs, credentials);
		MongoDatabase mongoDatabase = client.getDatabase("databaseName");
		
		// 联合查询条件
		List<Bson> aggregationList = new LinkedList<Bson>();
		
		// 主表查询条件
		String[] brokerNumsArray = broker_nums.split(",");
		aggregationList.add(Aggregates.match(Filters.in("BROKER_NUM", brokerNumsArray)));
		
		// 从表名、主表连接字段、从表连接字段、别名
		aggregationList.add(
			Aggregates.lookup(CacheConstants.DOCUMENT_NAME, "CUST_NUM", "CUST_NUM", "BROKER_CUST")
		); 
		
		// 从表查询条件
		aggregationList.add(Aggregates.match(
				Filters.and(
						Filters.eq("BROKER_CUST.LABL_THME_ID", labl_thme_id), 
						Filters.eq("BROKER_CUST.LABL_GRP_CLAS_ID", labl_grp_clas_id), 
						Filters.eq("BROKER_CUST.LABL_GRP", labl_grp), 
						Filters.in("BROKER_CUST.LABL_ID", label_id) 
						)
				));
		if (custNums != null && custNums.size() != 0) {
			aggregationList.add(Aggregates.match(
					Filters.and(
							Filters.in("BROKER_CUST.CUST_NUM", custNums.toArray())
							)
					));
		}
		
		// 只查询CUST_NUM列
		BasicDBObject basicDBObject = new BasicDBObject();
		basicDBObject.put("CUST_NUM", true);
		basicDBObject.put("_id", false);
		aggregationList.add(
				Aggregates.project(basicDBObject)
				); 
		// 从第0条开始查,查50条记录
//		aggregationList.add(Aggregates.skip(0));
//		aggregationList.add(Aggregates.limit(50));
		AggregateIterable<Document> labelList = mongoDatabase.getCollection(CacheConstants.HTQH_BROKER_CUST_RELA).aggregate(aggregationList);
		
		long endTime = System.currentTimeMillis();
		logger.info("耗时:{}ms", endTime - beginTime);
		
        // 打包出参
		List<String> resultList = new LinkedList<String>();
		for (Document dr : labelList) {
			if (resultList.contains(dr.getString("CUST_NUM"))) {
				continue;
			}
			resultList.add(dr.getString("CUST_NUM"));
		}
		return resultList;
	}
}

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中使用 MongoDB 进行多关联查询可以通过使用 MongoDB 的聚合管道(Aggregation Pipeline)来实现。聚合管道是一系列操作步骤,可以将多个的数据进行关联和处理。 下面是一个示例代码,展示了如何在 Java 中使用 MongoDB 的聚合管道进行多关联查询: ```java import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Filters; import com.mongodb.client.model.LookupOperation; import org.bson.Document; public class Main { public static void main(String[] args) { // 连接 MongoDB try (MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017")) { MongoCollection<Document> ordersCollection = mongoClient.getDatabase("mydb").getCollection("orders"); MongoCollection<Document> customersCollection = mongoClient.getDatabase("mydb").getCollection("customers"); // 定义聚合管道操作 LookupOperation lookupOperation = LookupOperation .from("customers", "customerId", "_id", "customerInfo"); // 构建聚合管道 AggregateIterable<Document> result = ordersCollection.aggregate(Arrays.asList( Aggregates.match(Filters.eq("status", "completed")), lookupOperation )); // 遍历查询结果 for (Document document : result) { System.out.println(document); } } } } ``` 上述示例代码中,我们假设有两个集合:`orders` 和 `customers`。`orders` 集合中的每个文档包含一个 `customerId` 字段,该字段与 `customers` 集合中的 `_id` 字段关联。我们使用 `LookupOperation` 来进行关联查询,并使用 `match` 操作来过滤出状态为 "completed" 的订单。 请注意,这只是一个简单的示例,实际的多关联查询可能需要更复杂的聚合管道操作来满足特定的需求。你可以根据自己的实际情况进行相应的调整和扩展。 希望能帮助到你!如果有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值