我正在玩Mongo制作一个类似SO的宠物项目,我想实现帖子标签。每个标签都有一个名称和一个slug(在URL中用作id的字符串),一个帖子有多个标签。我希望能够创建诸如“查找帖子,其中包含标签A,没有标签B”的查询,我想知道这样做的方法是什么。
一种方法是在每个帖子中存储一个标签ID数组 - 这将使所述查询变得容易,但每个帖子需要额外的一个来获取标签名称和slug。另一种方法是为每个帖子存储[标签名称,标签slug]的数组,但我不确定我是否能够在find
中使用该信息。
还有其他方法,对mongo更好吗?我是NoSQL的新手,所以我很欣赏任何有关如何实现这一点的建议。另外,我正在使用PHP绑定,但这可能无关紧要。
答案 0 :(得分:42)
如果您使用的标签及其各自的标签不太可能发生变化,我认为您的第二种方法更好。但是,我建议进行一些小改动 - 而不是存储[name, slug]
数组,通过创建标记子文档使字段显式,如本示例post
文档中所示:
{
"_id" : ObjectId("4ee33229d8854784468cda7e"),
"title" : "My Post",
"content" : "This is a post with some tags",
"tags" : [
{
"name" : "meta",
"slug" : "34589734"
},
{
"name" : "post",
"slug" : "34asd97x"
},
]
}
然后,您可以使用点符号查询具有特定标记的帖子,如下所示:
db.test.find({ "tags.name" : "meta"})
因为tags
是一个数组,所以mongo足够聪明,可以将查询与数组的任何元素相匹配,而不是整个数组,并且点符号允许您匹配特定字段。
要查询包含特定标记的帖子 ,请使用$ne
:
db.test.find({ "tags.name" : { $ne : "fish" }})
要查询包含一个标记但不包含另一个标记的帖子,请使用$and
:
db.test.find({ $and : [{ "tags.name" : { $ne : "fish"}}, {"tags.name" : "meta"}]})
希望这有帮助!