dot 快速的未来正在您的城市举办活动。

加入我们参加 Redis 发布会

如何使用 Redis 消除浪费,促进绿色星球

什么会在一年内产生 3 亿吨固体废物?美国消费者。其中只有一半直接进入垃圾填埋场进行储存。当一个垃圾填埋场超过容量时,就会被封存以防止泄漏。 同时,在地表深处,垃圾继续分解,产生许多有毒副产品,如渗滤液(被污染的水)。还会产生一氧化碳,导致空气中的二氧化碳水平上升。 

同样令人不寒而栗的是,这些垃圾填埋场垃圾中的 50% 是可以堆肥、重复使用和回收的。认识到这是完全可以避免的,Rajesh Ramamurthy 创建了一个非凡的应用程序,GreenEarth,它可以减少浪费,促进绿色星球。 该应用程序创建了一个平台,来自世界各地的人们可以在这里找到利用普通家用垃圾将它们重新用于有用物品或创意艺术项目的项目。 

Redis 用于从云数据库中检索用户信息,并以超高效率存储单个用户属性。这对 Greener Earth 的功能至关重要,因为数据处理需要高速执行,以最大限度地提高用户体验。 

让我们看看 Rajesh 如何将这个创新应用程序变为现实。但在深入了解之前,我们想指出,我们在 Redis Launchpad 上有 29 个其他激动人心的应用程序,这些应用程序正在改善日常生活。 因此,请确保在阅读完这篇文章后浏览一下。 

https://www.youtube.com/embed/iK2IeM9xI4g
  1. 您将构建什么?
  2. 您需要什么?
  3. 架构
  4. 入门
  5. 设置功能
  6. 工作原理

1. 您将构建什么?

一个应用程序。一个社区和一个平台,让人们帮助拯救地球。该应用程序将有环保意识的人们与利用家用物品的项目联系起来。例如,如果用户想利用他们空的锡罐,Green Earth 会将他们与演示如何使用这些物品创建有用的家用物品的项目联系起来。 

下面我们将向您展示如何通过按时间顺序执行每个步骤来构建此应用程序。我们还将重点介绍您需要的组件及其功能。

GreenEarth website with a description of how to repurpose tin cans into flower pots, pencil holders, even tumblers.

2. 您需要什么?

3. 架构

Image showing the architecture of building an app with Redis.

4. 入门

  • 安装 NPM
  • 设置启用了 RedisJSON 模块的 Redis 企业云数据库

安装 NPM

brew install npm

设置 Redis 企业云数据库

创建您的免费 Redis 企业云帐户。单击“立即开始”后,您将收到一封包含激活帐户链接的电子邮件,以完成注册流程。

My Image

单击此链接,在 Redis 企业云数据库下启用 RedisJSON 模块。

克隆存储库

git clone https://github.com/redis-developer/greenearth

安装 NPM 依赖项

更改目录到 greenearth 目录并安装所需的依赖项

npm install

配置 index.js

要连接到启用了 RedisJSON 的 Redis 企业云数据库,您需要在 index.js 中编辑以下代码。

const client = redis.createClient({
     port      : // database port,
     host      : // database url,  
     password  : // database password
});

启动应用程序

您还需要运行 npm start 以在 https://#:3000 上启动本地服务器。

npm start

5. 设置功能

下面列出了应用程序正常运行所需的许多功能。让我们看看需要做些什么。 

用户

  • 注册

创建用户帐户。

SADD – 将用户名添加到全局用户集中

HMSET – 创建包含哈希密码、描述和个人资料图片的用户对象

  • 登录

允许用户登录现有帐户。

async function login(name, password) {
	if (client.sismember(['users', name])) {
		const hash = crypto.createHash('sha256');
		hash.update(password);
		var pwdhash = hash.digest('hex');
		const hget = promisify(client.hget).bind(client);
		var pwd = await hget([name, 'pwd']);

		if (pwdhash === pwd) {
			console.log("Successful sign-in");
			var token = uuidv4();
			const hset = promisify(client.hset).bind(client);
			await hset(['active', token, name]);
			return token;
		} else {
			console.log("Incorrect password");
			return null;
		}
	} else {
		console.log("Account does not exist");
		return null;
	}
}

SISMEMBER – 检查输入的用户名是否为有效成员 

HGET – 通过检索已注册的密码并进行比较来验证输入的密码

HSET – 将用户名与生成的会话令牌添加到活动用户组 br>

  • 注销

从已登录的帐户中注销。

async function logout(token) {
var name = await authUser(token);
	console.log(token);
	console.log(name);
	if (name == null) {
		console.log("Not signed in");
	} else {
		const hdel = promisify(client.hdel).bind(client);
		await hdel(['active', token]);
		console.log("Successful logout");
	}
}

HGET – 从提供的会话令牌中检索用户

HDEL – 从活动用户组中删除用户和会话令牌

  • 用户信息

检索指定用户的(用户名、描述、个人资料图片)信息。

app.get('/userInfo', async (req, res) => {
  var name = req.query.name;
  const hmget = promisify(client.hmget).bind(client);
  var user = await hmget(name, 'id', 'description', 'image');
  res.send([name, ...user]);
})

HMGET – 从提供的属性中检索用户数据

  • 设置字段

设置指定用户的特定属性(描述、个人资料图片)。

async function setField(token, field, value) {
var name = await authUser(token);
	const hmset = promisify(client.hmset).bind(client);
	await hmset(name, field, value);

}

HMSET – 使用提供的设置用户属性数据

帖子

  • 添加帖子

从提供的用户信息添加帖子。

app.get('/allPosts', async (req, res) => {
	var name = req.query.name;
	const hget = promisify(client.hget).bind(client);
	const lr = promisify(client.lrange).bind(client);
	const hgetall = promisify(client.hgetall).bind(client);

	const json_get = promisify(client.json_get).bind(client);

	var id = await hget([name, 'id']);
	var posts = await json_get(id);
	posts = JSON.parse(posts);
	var newposts = {"posts": []};
	if (posts != null) {
		for (var i = 0; i < posts.length; i++) {
			var p = posts[i];

			if (p["visibility"] === "on") {
				newposts["posts"].push(p);
			}
		}
	}
	console.log(newposts);
	res.send(newposts);

})

HGET – 检索用户帖子列表 ID

JSON.SET – 从提供的创建帖子信息并将信息添加到用户帖子列表中

JSON.GET – 检索用户帖子列表

  • 编辑帖子

编辑用户创建的现有帖子。

async function editPost(token, pid, title, description, image, recipe, steps, visibility) {
	var name = await authUser(token);
	const hget = promisify(client.hget).bind(client);
	const json_get = promisify(client.json_get).bind(client);
	const json_set = promisify(client.json_set).bind(client);
	var id = await hget([name, 'id']);

	var posts = await json_get(id, ".");
	var globalPosts = await json_get('globalPosts', ".");
	posts = JSON.parse(posts);
	globalPosts = JSON.parse(globalPosts);
	console.log(posts);

	const newpost = {
	  pid: pid,
	  title: title,
	  description: description,
	  author: "",
	  image: image,
	  recipe: recipe,
	  steps: steps,
	  comments: [],
	  visibility: visibility
	}
	var vis;

	if (posts != null) {
		for (var i = 0; i < posts.length; i++) {
			if (posts[i]["pid"] === pid) {
				vis = posts[i]["visibility"];
				newpost.author = posts[i]["author"];
				newpost.comments = posts[i]["comments"];
				posts[i] = newpost;

				break;
			}
}
	}
	if (vis === "on") {
		if (globalPosts != null) {
			for (var i = 0; i < globalPosts.length; i++) {
				if (globalPosts[i]["pid"] === pid) {
					globalPosts[i] = newpost;
					if (visibility === "off") {
						globalPosts.splice(i, 1);
					} else if (visibility === "on") {
						globalPosts[i] = newpost;
					}
					break;
				}
			}
		}
	} else {
		if (visibility === "on") {
			globalPosts.push(newpost);
		}
	}
	await json_set(id, '.', JSON.stringify(posts));
	await json_set('globalPosts', '.', JSON.stringify(globalPosts));
	console.log("Post edited");
}

HGET – 检索用户帖子列表 ID

JSON.SET – 使用用户帖子列表中提供的替换现有信息帖子

JSON.GET – 检索用户帖子列表

  • 删除帖子

删除用户创建的现有帖子。

async function deletePost(token, pid) {
	var name = await authUser(token);
const hget = promisify(client.hget).bind(client);
	var id = await hget([name, 'id']);


	const json_get = promisify(client.json_get).bind(client);
	const json_set = promisify(client.json_set).bind(client);
	var posts = await json_get(id, ".");
	posts = JSON.parse(posts);
	console.log(posts);
	if (posts == null) {
		posts = [];
	}
	var vis;
	for (var i = 0; i < posts.length; i++) {
		if (posts[i]["pid"] == pid) {
			vis = posts[i]["visibility"];
			posts.splice(i, 1);
			break;
		}
	}
	await json_set(id, '.', JSON.stringify(posts));

	if (vis === "on") {
		var posts = await json_get('globalPosts', ".");
		posts = JSON.parse(posts);
		if (posts == null) {
			posts = [];
		}
		for (var i = 0; i < posts.length; i++) {
			if (posts[i]["pid"] == pid) {
				posts.splice(i, 1);
				break;
			}
		}
		await json_set('globalPosts', '.', JSON.stringify(posts));
	}

}

HGET – 检索用户帖子列表 ID

JSON.SET – 删除帖子并将帖子添加到用户帖子列表中

JSON.GET – 检索用户帖子列表

  • 帖子信息

检索指定帖子的(标题、描述、图片、材料、说明、评论)信息。

app.get('/postInfo', async (req, res) => {
	var pid = req.query.pid;
	var post = await findPostByID(pid);
	res.send(post);

})

JSON.GET – 从用户帖子列表中检索帖子

  • 所有帖子

检索所有全局帖子或由特定用户创建的帖子。

app.get('/allPosts', async (req, res) => {
	var name = req.query.name;
	const hget = promisify(client.hget).bind(client);
	const lr = promisify(client.lrange).bind(client);
	const hgetall = promisify(client.hgetall).bind(client);

	const json_get = promisify(client.json_get).bind(client);

	var id = await hget([name, 'id']);
	var posts = await json_get(id);
	posts = JSON.parse(posts);
	var newposts = {"posts": []};
	if (posts != null) {
		for (var i = 0; i < posts.length; i++) {
			var p = posts[i];

			if (p["visibility"] === "on") {
				newposts["posts"].push(p);
			}
		}
	}
	console.log(newposts);
	res.send(newposts);
})

JSON.GET – 检索用户或全局帖子列表

  • 所有草稿

检索用户创建的所有草稿。

app.get('/allDrafts', async (req, res) => {
	var name = req.query.name;
	const hget = promisify(client.hget).bind(client);
	const lr = promisify(client.lrange).bind(client);
	const hgetall = promisify(client.hgetall).bind(client);

	const json_get = promisify(client.json_get).bind(client);

	var id = await hget([name, 'id']);
	var posts = await json_get(id);
	posts = JSON.parse(posts);
	var newposts = {"posts": []};
	if (posts != null) {
		for (var i = 0; i < posts.length; i++) {
			var p = posts[i];

			if (p["visibility"] === "off") {
				newposts["posts"].push(p);
			}
		}
	}
	console.log(newposts);
	res.send(newposts);
})

JSON.GET – 检索用户草稿列表

  • 添加评论

允许用户对帖子发表评论。

HGET – 检索帖子评论列表 ID

JSON.SET – 创建评论并添加到帖子评论列表中

JSON.GET – 检索帖子评论列表

6. 工作原理

任何使用该网站的人都可以搜索他们拥有的材料或他们感兴趣的项目。要开始,只需访问 Green Earth 主页。 

The homepage screen of GreenEarth page with image of the Earth in space.

如何查找项目

单击页面顶部的“帖子”选项卡。这将带您到一个搜索栏,您可以在这里输入您要回收的家用物品。因此,例如,如果您有很多锡罐想重新利用,只需输入“锡罐”或该关键字的变体(见下图)。 

Image of tin cans repurposed as flower pots in the GreenEarth site.

输入后,将显示一个需要您家用物品的项目列表。单击其中一个结果将带您到该帖子的项目页面。

在这里,您将发现有关该项目的所有需要了解的信息,从用户评论到所需的材料,以及您需要遵循的说明(见下图)。

The Description section of the GreenEarth site.
The Materials section of the GreenEarth site.

如何创建帐户

单击页面顶部的“注册”选项卡。在这里,您可以为您的帐户创建用户名和密码。 

创建帐户并登录后,下一步将更新您的个人资料。您可以通过单击导航栏顶部的用户名并选择“个人资料”来执行此操作。

然后您将被定向到您的个人资料页面,该页面将为空(见下图)。

A page in the GreenEarth site for filling out a profile description.

从这里,您可以更新个人资料的每个部分,包括个人资料照片和简介。 

如何发表评论

设置个人资料后,您就可以对帖子发表评论了。为此,首先找到您要评论的帖子(请参阅“如何查找项目”部分)。每个帖子的评论部分位于项目页面的底部(见下面的示例)。 

Showing the Comments section of GreenEarth website.

如何创建帖子

要创建帖子,您首先需要转到您的个人资料信息中心。单击个人资料右上角的“+”符号(见下图)。 

A dashboard for creating a post in GreenEarth app with picture of Gandalf.

然后您将被定向到“创建帖子页面”。从这里,您将看到许多需要填写不同的字段,从项目名称到说明,再到使该项目成为现实所需的材料。 

在每个部分中添加您的项目的详细信息,如下所示。  

GreenEarth site image of a repurposed plastic bottle as a sprinkler.
A list of materials.

完成每个部分后,您将在页面底部可以选择删除、保存或发布此帖子。 

如何编辑帖子

所有草稿和帖子都将显示在您的个人资料信息中心中。

A dashboard for editing a post in GreenEarth.

要编辑其中一个,首先点击你要编辑的帖子或草稿。接下来,点击页面左下角的编辑按钮。或者,你可以点击旁边垃圾桶图标删除帖子。 

结论:用 Redis 倡导绿色运动 

气候变化已经成为每个人的关注点,促使人们采取更绿色的生活方式。但要使绿色倡议取得成果,在线平台需要高效且由能够高速传输数据的数据库驱动。 

这是因为任何延迟都会影响用户体验,并让人们远离这些平台。然而,借助 Redis,GreenEarth 能够以如此快的速度运行,以至于它使应用程序中的所有组件都能够更加互连。 

多亏了 Redis,从云数据库中检索用户信息以及存储单个用户属性变得轻而易举。从头到尾,所有操作都以超高的效率执行。 

A redislaunchpad apps banner

谁开发了这个应用?

Rajesh Ramamurthy

Rajesh Ramamurthy

Rajesh 是科技领域公认的解决问题的高手,他为客户提供复杂问题的简单解决方案。 

一定要查看他的 GitHub 页面,看看他参与过哪些其他项目。 

如果你想了解更多关于这个应用如何部署的信息,请务必查看Rajesh 在 YouTube 上发布的视频

我们还精选了一系列不同的应用程序,供您在Redis Launchpad 上查看,全球的程序员正在利用 Redis 的力量改变人们的日常生活。 查看它。获得灵感。加入其中。