If I use the following filter, it’s OR

filter: {tags: {elemMatch: {contentful_id: {eq: $tagId}, name: {eq: "published"}}}}

because filters over multiple fields are OR

filter: {
tags: {
elemMatch: {
contentful_id: {
eq: $tagId
},
name: {
eq: "published"
}
}
}
}

resulting in

  • tag.id === $tagId
  • OR
  • tag.name === “published”

If instead I use (abuse) the different matcher things for the same field, it is AND

filter: {tags: {elemMatch: {contentful_id: {}, name: {eq: "published", in: "i.book", nin: "page"}}}}

formatted:

filter: {
tags: { // only 1 field
elemMatch: {
name: {
eq: "published",
in: "i.book",
nin: "page"
}
}
}
}

resulting in:

  • tag.name === “published”
  • AND
  • tag.name === “i.book”
  • AND
  • tag.name !== “page”

I’m pretty sure I’m abusing the ‘in’ operator here, to have a second ’eq’. And I assume the ‘glob’ and ‘regex’ can be used the same way. So we can use 4 x ‘===’ (eq, in, glob, regex) and 2 x ‘!==’ (ne,nin)