Вопрос

I have a Django application with the following postgres db tables: Publication and Tag

Publication {
    title
    tags
}

Tag {
    title
}

Tag and Publication have a many to many relationship.

What I want to do is do an and/or combo search: for example, let's say I have four tags: A, B, C, D. I want to find all publications that have an A OR B tag associated with it, AND a C OR D tag associated with it. For example, in a search field I might enter: (A || B) && (C || D). In other words, the results should yield publications that have at least one tag from each 'or' pair.

I'd like to be able to enter the tag titles and return the publication titles.

I tried doing this using a Django filter, and even asked this question yesterday: What is an Efficient Way to do an AND/OR Search Django-Postgres App? and finally realized that doing a raw sequel query was probably better. The only problem: I've never written a raw sequel statement.

I just spent the last couple of hours looking at this question: How to filter SQL results in a has-many-through relation, and trying to apply it to my circumstance, but I'm too much of a newbie to be able to do it.

Given my models, can anyone show me how to construct this query?

Это было полезно?

Решение

Of course, you would have a table implementing the n:m relationship. Like

publication_tag {
    publication_id
    tag_id
}

Then your query could look like:

SELECT p.publication_id, p.publication
FROM   publication p
WHERE  EXISTS (SELECT 1 FROM publication_tag
               WHERE  publication_id = p.publication_id
               AND    tag_id IN ('A', 'B')
              )
AND    EXISTS (SELECT 1 FROM publication_tag
               WHERE  publication_id = p.publication_id
               AND    tag_id  IN ('C', 'D')
              )

This should be among the fastest possible solutions. You already found the go-to question with a lot more sample queries for relational division.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top