使用Kettle在MongoDB中创建子表

时间:2013-08-12 01:59:13

标签: mongodb etl kettle

我有两个PostgreSQL表,其中包含以下数据:

房屋

-# select * from houses;
 id |    address
----+----------------
  1 | 123 Main Ave.
  2 | 456 Elm St.
  3 | 789 County Rd.
(3 rows)

-# select * from people;
 id | name  | house_id
----+-------+----------
  1 | Fred  |        1
  2 | Jane  |        1
  3 | Bob   |        1
  4 | Mary  |        2
  5 | John  |        2
  6 | Susan |        2
  7 | Bill  |        3
  8 | Nancy |        3
  9 | Adam  |        3
(9 rows)

在Spoon中我有两个表输入第一个名为 House Input 的SQL:

SELECT
  id
, address
FROM houses
ORDER BY id;

第二个表输入使用SQL命名为人员输入

SELECT
  "name"
, house_id
FROM people
ORDER BY house_id;

我有两个表输入进入合并加入,使用住宅输入作为第一步,密钥为{{1} }和人员输入作为第id项的第二步。

然后我将这个带到 MongoDb输出,数据库演示,集合房屋和Mongo文档字段house_idaddress。 (因为我期望MongoDB分配name)。

当我运行转换并从Mongo shell中键入_id时,我得到:

db.houses.find();

想要得到的是:

{ "_id" : ObjectId("52083706b251cc4be9813153"), "address" : "123 Main Ave.", "name" : "Fred" }
{ "_id" : ObjectId("52083706b251cc4be9813154"), "address" : "123 Main Ave.", "name" : "Jane" }
{ "_id" : ObjectId("52083706b251cc4be9813155"), "address" : "123 Main Ave.", "name" : "Bob" }
{ "_id" : ObjectId("52083706b251cc4be9813156"), "address" : "456 Elm St.", "name" : "Mary" }
{ "_id" : ObjectId("52083706b251cc4be9813157"), "address" : "456 Elm St.", "name" : "John" }
{ "_id" : ObjectId("52083706b251cc4be9813158"), "address" : "456 Elm St.", "name" : "Susan" }
{ "_id" : ObjectId("52083706b251cc4be9813159"), "address" : "789 County Rd.", "name" : "Bill" }
{ "_id" : ObjectId("52083706b251cc4be981315a"), "address" : "789 County Rd.", "name" : "Nancy" }
{ "_id" : ObjectId("52083706b251cc4be981315b"), "address" : "789 County Rd.", "name" : "Adam" }

}

我知道为什么我得到了我所得到的东西,但似乎无法在网上或示例中找到任何东西让我到达我想去的地方。

我希望有人可以朝着正确的方向推动我,指出一个更接近我想要完成的事情的例子,或者告诉我这不属于Kettle应该做的事情(希望不是后者)。

1 个答案:

答案 0 :(得分:0)

结果是 MongoDB输出步骤中创建子表。

首先确保您在配置连接标签上选中 Upsert 修改器更新

然后在 Mongo Documents字段标签上输入以下内容(第一行是列名):

Name    | Mongo document Path | Use field name | Match field for upsert | Modifier operation | Modifier policy
--------+---------------------+----------------+------------------------|--------------------+---------------- 
address |                     | Y              | N                      | N/A                | Insert
address |                     | Y              | Y                      | N/A                | Insert
name    | people[0]           | Y              | N                      | $set               | Insert
name    | people[1]           | Y              | N                      | $push              | Update

现在,当我运行db.houses.find();时,我得到了:

{ "_id" : ObjectId("520ccb8978d96b204daa029d"), "address" : "123 Main Ave.", "people" : [ { "name" : "Fred" }, { "name" : "Jane" }, { "name" : "Bob" } ] }
{ "_id" : ObjectId("520ccb8978d96b204daa029e"), "address" : "456 Elm St.", "people" : [ { "name" : "Mary" }, { "name" : "John" }, { "name" : "Susan" } ] }
{ "_id" : ObjectId("520ccb8a78d96b204daa029f"), "address" : "789 County Rd.", "people" : [ { "name" : "Bill" }, { "name" : "Nancy" }, { "name" : "Adam" } ] }

我想注意两件事:

  1. 这假设我的地址是唯一的,而且我的名字在房子里是独一无二的。如果不是这种情况,我需要将我的ID从我的OLTP表格转换为MongoDB中的id(非_id)字段,并将匹配字段upsert 放在我的房屋ID上。
  2. 正如@G Gordon Worley III上面指出的那样,如果这两个表位于同一个数据库中,我可以在表输出步骤中进行连接,这将是一个两步转换(更快)。