私は現在、画像を保存し、これらの画像にタグを付けることができるアプリケーションを作成しています。私は Python と Peewee ORM (http://charlesleifer.com/docs/peewee/) を使用しています。これは Django の ORM に非常に似ています。
私のデータモデルは次のようになります(簡略化):
class Image(BaseModel):
key = CharField()
class Tag(BaseModel):
tag = CharField()
class TagRelationship(BaseModel):
relImage = ForeignKeyField(Image)
relTag = ForeignKeyField(Tag)
これで、特定のタグ セットを持つすべての画像をクエリする方法を概念的に理解できました。
SELECT Image.key
FROM Image
INNER JOIN TagRelationship
ON Image.ID = TagRelationship.ImageID
INNER JOIN Tag
ON TagRelationship.TagID = Tag.ID
WHERE Tag.tag
IN ( 'A' , 'B' ) -- list of multiple tags
GROUP BY Image.key
HAVING COUNT(*) = 2 -- where 2 == the number of tags specified, above
ただし、より複雑な検索もできるようにしたいと考えています。具体的には、「すべてのタグ」のリストを指定できるようにしたいと考えています。つまり、画像には、指定されたすべてのタグと、「任意」のリストおよび「なし」のリストが含まれている必要があります。
編集:これを少し明確にしたいと思います。具体的には、上記のクエリは「すべてのタグ」スタイルのクエリです。指定されたすべてのタグを持つ画像を返します。次のようなものを指定できるようにしたい:「タグ(緑、山)、タグ(背景、風景)のいずれかを持ち、タグ(デジタル、描画)を持たないすべての画像を教えてください」。
さて、理想的には、これを 1 つの SQL クエリにしたいと思います。なぜなら、LIMIT と OFFSET を使用すると、ページネーションが非常に簡単になるからです。私は実際に、すべてをPythonセットにロードしてから、さまざまな交差演算子を使用する実装を行っています。私が疑問に思っているのは、これを一度に行う方法があるかどうかです。
また、興味のある方のために、Peewee を使用して上記のクエリを表す方法について Peewee の作成者にメールを送信したところ、彼は次の解決策で応答しました。
Image.select(['key']).group_by('key').join(TagRelationship).join(Tag).where(tag__in=['tag1', 'tag2']).having('count(*) = 2')
または、代わりに、短いバージョン:
Image.filter(tagrelationship_set__relTag__tag__in=['tag1', 'tag2']).group_by(Image).having('count(*) = 2')
お時間をいただきありがとうございます。