Prismic.predicates crashes with existing fields

I'm trying to get all of the articles written by a specific author. My article structure is as follows:

article: { data: 
   { article_authors: [ 
      { author: { 
         id: "abcd", 
         type: "author",
         uid: "author-name"
      } 
      } 
   ]},
   uid: 'my-uid,
}

I can get all articles with $prismic.predicates.at('document.type', 'article'),
I've been able to run:

const document2 = await $prismic.api.query([
    $prismic.predicates.at('document.type', 'article'),
    $prismic.predicates.at('my.article.uid', 'my-uid'),
    $prismic.predicates.has('my.article.uid'),
]);

successfully, but when I try something like:

const document2 = await $prismic.api.query([
    $prismic.predicates.at('document.type', 'article'),
    $prismic.predicates.has('my.article.data'),
]);

The query crashes. Does anyone know why prismic seems to work with some fields but not others?

Hello @technical1, thanks for reaching out.
That query should work just fine. You can combine $prismic.predicates.at('document.type', 'article'), and $prismic.predicates.has('my.article.uid'). Could you send us any errors that you see on your project logs?

You can try running that query in your repositories REST API browser. Test it first and then add it to your project: https://your-repo-name.prismic.io/api/v2

Hello @Pau, thanks for responding.

The first query combining $prismic.predicates.at('document.type', 'article') , and $prismic.predicates.has('my.article.uid') does work. My problems begin when trying to query the author.

I have tried using predicates.fulltext() as well. With this I've been able to find text in the article body but not the author.

I think the issue comes from the author being a custom type. None of the predicates I've tried so far have been able to interact with it. When using $prismic.predicates.has('my.article.data.article_authors') I get the following error:

{"type":"api_parsing_error","message":"[function has(..)] unexpected field 'my.article.data.article_authors' on line:1 col:37 in query '[[at(document.type, \"article\")][has(my.article.data.article_authors)]]'\n[[at(document.type, \"article\")][has(my.article.data.article_authors)]]\n ^\n","pos":{"line":1,"column":37,"id":0,"location":"query"}}

Ok, I see. I think it is only necessary to rewrite the query. So if Author is a Custom Type, what is article_authors, a Content Relations field?

If article_authors is a text field, then if you can do a fullText search, like so:

$prismic.predicates.fulltext(my.article.article_authors, 'Jane John')

"article_authors" : { "type" : "Group", "config" : { "fields" : { "author" : { "type" : "Link", "config" : { "select" : "document", "customtypes" : [ "author" ], "label" : "Author" } } }, "label" : "Article authors" } },

article_authors is a group type. Above is the JSON as seen in the article type.

$prismic.predicates.fulltext('my.article.article_authors.author', 'my-author-name'), will run but returns no results. $prismic.predicates.fulltext('my.article.article_authors', 'my-author-name'), will crash.

I was reading similar issues and am using fetchLinks: '[author.author_name, author.uid]', to no avail.

This is the full query I run:
const myArticles = await $prismic.api.query(
[
$prismic.predicates.at('document.type', 'article'),
$prismic.predicates.fulltext('my.article.article_authors.author', 'my-author-name'),
],
{
orderings: '[document.last_publication_date desc]',
fetchLinks: 'author.uid',
},
);

The fulltext requires a different syntax: $prismic.predicates.fulltext('author.author_name'). The query understands that this field is inside the article type.

With the following query:

const document2 = await $prismic.api.query(
[
$prismic.predicates.at('document.type', 'article'),
$prismic.predicates.fulltext('author.author_name', 'My Author'),
],
{
orderings: '[document.last_publication_date desc]',
fetchLinks: ['author.author_name', 'author.author_position'],
},
);

I get the following error:
{"type":"api_parsing_error","message":"[function fulltext(..)] unexpected field 'author.author_name' on line:1 col:42 in query '[[at(document.type, \"article\")][fulltext(author.author_name, \"My Author\")]]'\n[[at(document.type, \"article\")][fulltext(author.author_name, \"My Author\")]]\n ^\n","pos":{"line":1,"column":42,"id":0,"location":"query"}}

Hello @technical1, sorry for the back n forth. One of my colleagues just confirmed that fetchLinks can not retrieve content from groups. That's why you're finding this roadblock.

Here's the list of limitations:

  • Embed
  • GeoPoint
  • Link
  • Link to Media
  • Rich Text (anything other than the first element)
  • Any field in a Group or Slice

So my best bet is to query all articles and then loop through them to find all the ones that match my author?

If the UID is the name of the author, it should work with that.

The uid is the name of the author (minus capitalisation and using '-' instead of spaces). This is a field I don't need fetchLinks for in a query. Is there some wizardry that allows me to use predicate.fulltext on this field?

The looping solution I mentioned above was my first implementation, I'm just concerned about latency once more articles are added to the site.

Yes, you can use the fulltext search with the uid field. This search param considers Rich Text, Title, Key Text, Select, and UID fields.

$prismic.predicates.fulltext('my.page.uid','my author name')

I have been unsuccessful in querying the uid field with $prismic.predicates.fulltext('my.author.uid', 'my-author-name'),

$prismic.predicates.has('my.author.uid'), doesn't return any results either.

It's odd that the first one doesn't work. What's the URL of your repository and the UID of the document you're looking for?

has('my.author.uid') isn't necessary because UID fields are the only required field in Prismic.

Here is the URL of the repository
swim-drink-fish.prismic.io - what we are trying to achieve is outlined in a comment below.

Perhaps we need to define the authors for article type differently?

If I want to select all articles that are written by an author, and an article can have multiple authors, how should I define that as a type such that I can make a single query that selects only those articles written by a specific author?

i.e.
article1 written by [dude1, dude2]
article2 written by [dude1]

I want to make a query like:
at("document.type", "article")
at("author.uid", "dude2")

and have only "article1" show up.

In SQL this would be something like "SELECT a.* FROM articles a, authors u WHERE u.uid = 'dude2' and a.uid = u.uid".

One would assume querying for all articles just to then filter them locally based on a specific key/value is a bad way to do this.

Ok in that case there's no way to avoid the article2 to appear in the API response cause the query doesn't work as an OR logical operator.

I'm not sure I understand.

I'm not trying to use an OR operator, I'm trying to use an AND operator. The goal is to get all documents of type article AND have a specific author uid

Oh ok ok, I understand. In that case, instead of using predicates, you can use query methods. Like getByUID:

client.getByUID("article", "dude2")

I'm fairly certain making a query by UID selects all articles which have the UID dude2. (a UID query on articles for a specific author UID indeed returns no articles):

What we want to get is all articles that have a specific author dude2 within a "field group" in the article.

When I make a query for a specific article the document result I get is a set of values and a data object which contains an array of author objects calledarticle_authors:

{
   ...
      data: {
             article_authors: [
​​​                   0: { ​​​​
                     author: { id: <author-id>, type: "author", lang: "en-ca", … }
​​​​                   },
             ]
      }
(etc...)

So, we have a custom document of type article with a repeatable group field which has a collection of authors that are constrained to author custom type, because that seemed like a sensible way to go about this.

What we're trying to represent in this custom type are articles that have authors and co-authors, and be able to retrieve all articles which an author has been the main author or co-author. (Basically, if the article has any author with a specific id)

Currently what we're doing is retrieving all articles and then going through linearly and investigating each author in the list. That seems non-optimal, as this is a relatively simple use case with relational tables - surely there is a way to retrieve a set of documents based on uids of objects in a group field?