如何在Mongo中实现帖子标签?

Flu*_*ffy 21 mongodb

我正在和Mongo一起做一个类似SO的宠物项目,我想实现post标签.每个标签都有一个名称和一个slug(在URL中用作id的字符串),一个帖子有多个标签.我希望能够创建诸如"查找帖子,其中包含标签A,没有标签B"的查询,我想知道这样做的方法是什么.

一种方法是在每个帖子中存储一个标签ID数组 - 这将使所述查询变得容易,但是每个帖子需要额外的一个来获取标签名称和slug.另一种方法是在每个帖子中存储[标签名称,标签slug]的数组,但我不确定我是否能够在a中使用该信息find.

还有其他一些方法,对mongo更好吗?我是NoSQL的新手,所以我很欣赏任何有关如何实现这一点的建议.另外,我正在使用PHP绑定,但这可能无关紧要.

Rus*_*ell 44

如果您使用的标签及其各自的标志不太可能发生变化,我认为您的第二种方法更好.但是,我建议一个小的更改 - 而不是存储数组[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"
        },
    ]
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用点符号查询具有特定标记的帖子,如下所示:

db.test.find({ "tags.name" : "meta"})
Run Code Online (Sandbox Code Playgroud)

因为tags是一个数组,所以mongo足够聪明,可以将查询与数组的任何元素匹配,而不是整个数组,并且点符号允许您匹配特定字段.

要查询包含特定标记的帖子,请使用$ne:

db.test.find({ "tags.name" : { $ne : "fish" }})
Run Code Online (Sandbox Code Playgroud)

要查询包含一个标签但不包含另一个标签的帖子,请使用$and:

db.test.find({ $and : [{ "tags.name" : { $ne : "fish"}}, {"tags.name" : "meta"}]})
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 是否有必要在标签中添加slug?或者只是拥有一组值? (4认同)
  • 我认为slu is恰好是OPs方法的实现细节.你不需要它. (2认同)
  • 是否有一个返回所有标签的查询(如果您想制作标签云)?编辑:看起来这可能有用:http://stackoverflow.com/a/4977057/389812 (2认同)