Как реализовать теги записей в Mongo? - PullRequest
20 голосов
/ 10 декабря 2011

Я играю с Mongo, чтобы сделать проект, похожий на SO, и хочу реализовать теги post.У каждого тега есть имя и слаг (строка, которая будет использоваться в качестве идентификатора в URL), а у записи есть несколько тегов.Я хотел бы иметь возможность создавать запросы типа «найти сообщения, которые имеют тег A, не имеют тег B», и мне интересно, как это можно сделать.

В одну сторонузаключается в сохранении массива идентификаторов тегов с каждым сообщением - это облегчит указанный запрос, но потребует дополнительного для каждого сообщения, чтобы получить имя тега и слаг.Другой способ - сохранить массив [tag name, tag slug] с каждым сообщением, но я не уверен, что смогу использовать эту информацию в find.

.метод, который будет работать лучше для монго?Я новичок в NoSQL, поэтому я буду признателен за любые советы о том, как это можно сделать.Кроме того, я использую привязку PHP, но это не должно иметь значения.

1 Ответ

42 голосов
/ 10 декабря 2011

Если теги, которые вы используете, и их соответствующие слагы вряд ли изменятся, я думаю, что ваш второй подход - лучший.Однако я бы предложил небольшое изменение - вместо того, чтобы хранить массив [name, slug], сделайте поля явными, создав поддокумент тега, как в этом примере post document:

{
    "_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"}]})

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...