Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Querying richText field in GraphQL

default discord avatar
squareclamp2 years ago
17

Is it possible to do a full text search on richText field in posts? I was trying this in GraphQL -


{ Posts(where: { content: { contains: "content" } }, draft: true) { docs { id content } } }

Not sure on the the expected values for JSON fields in

Post_content_operator



type Post_content_operator { equals: JSON not_equals: JSON like: JSON contains: JSON exists: Boolean }
  • discord user avatar
    jmikrut
    2 years ago

    This is possible, but not in GraphQL unfortunately. Because GraphQL is so strict in its typing



    But in the REST API, here's how you'd do it



    ?where[content.children.text][like]=test

  • default discord avatar
    squareclamp2 years ago

    I see so, is it because the the type of content is JSON? If it was a string, would it work? Think if I could have a hidden field that is string for full text search. I'm not sure though what might be the best way to do full text search using Mongo.

  • discord user avatar
    jmikrut
    2 years ago

    100%



    very good call



    you should build that into a plugin actually



    it would be amazing



    Mongo does support full text search actually, but we have not yet wired it into Payload. That however will be making its way into core for sure

  • default discord avatar
    squareclamp2 years ago

    Thanks, I got something working using a hidden text field and

    beforeSave

    hook. I guess it could be packaged into a lightweight plugin.



    I'm doing this in the beforeSave hook for the collection -



    beforeChange: [ async ({ data, // incoming data to update or create with req, // full express request operation, // name of the operation ie. 'create', 'update' originalDoc, // original document }) => { data.indexableExcerpt = data.excerpt.flatMap( block => block.children.map( (b) => b.text)).join("") return data; // Return data to either create or update a document with } ]

    fields



    richText({ name: 'excerpt', }), { name: 'indexableExcerpt', type: 'text', index: true, admin: { hidden: true } }

    Is there a cleaner way to get rawText for richText field?

  • discord user avatar
    jmikrut
    2 years ago

    i think that's pretty nice tbh



    here's how we've done it before (the rich text list cell component)



    https://github.com/payloadcms/payload/blob/master/src/admin/components/views/collections/List/Cell/field-types/Richtext/index.tsx
  • default discord avatar
    squareclamp2 years ago

    Thanks, it seems like

    index: true

    would be kind of useless in this case. Since it probably just using a tree-based index. And we'd want to create text index and search operator for this use case which might be some work.

    https://www.digitalocean.com/community/tutorials/how-to-perform-full-text-search-in-mongodb

    I'll probably just go with something like Algolia for now. Will keep an eye out for full text index support or maybe contribute it 🙂



    IIUC, this would be scanning all documents even with index -



    { Posts(where: { indexableExcerpt: {contains: "small"} }, draft: true) { docs { id title excerpt } } }
  • default discord avatar
    bombnp2 years ago

    I actually did something similar to this. I created a function to recursively flatten all text elements, and put it to another hidden text field. Not sure if this can help.


    import { Descendant, Element, Text } from 'slate'
    
    export const flattenText = (obj: Descendant | Descendant[]): string => {
      if (Element.isElementList(obj) || Text.isTextList(obj)) {
        return obj.map(flattenText).join(' ')
      } else if (Element.isElement(obj)) {
        return flattenText(obj.children)
      } else if (Text.isText(obj)) {
        return obj.text
      } else {
        throw new Error('Invalid slate element:' + JSON.stringify(obj))
      }
    }
  • default discord avatar
    ssyberg2 years ago
    @495380410813906945

    even using agolia / 3rd party search, do you have an idea of how you'd integrate that in to Payload search?

  • default discord avatar
    squareclamp2 years ago

    I haven't tried Algolia. I've actually been wanting to try to create full text index manually or via Mongoose and verify if the index is used. If it is then perhaps we don't third part full text search provider.



    @364124941832159242

    Any suggestions on what might be a good place to create text index for a collection? I was think

    onInit

    in payload.init.

  • discord user avatar
    jmikrut
    2 years ago

    i would have a hook on the collection(s) that you want to index, and just keep the text index up to date whenever documents are created / updated



    not

    onInit

    that is how we do it for this site:



    https://hopenetwork.org

    take a look at the global search - it's all using Payload, and just uses

    afterChange

    hooks on pages, posts, etc.

  • default discord avatar
    squareclamp2 years ago

    Would it be possible to share snippet on how you might update index in the hook? I was expecting once you create index in

    onInit

    the index is updated automatically when fields change.



    The website search is looks great, and is very similar to my use case. One thing I recently realized was that adding

    highlights

    is an atlas only feature. So, you can only show documents but not highlight keywords.



    I actually really like the highlights (or underline) of the keyword when searching payload docs. Was curious if something like that might also be possible with MongoDB atlas.

  • discord user avatar
    jmikrut
    2 years ago

    that seems like it would be a frontend feature which should certainly be possible



    we will open-source our entire search index implementation for the Hope site



    that is a good call

  • default discord avatar
    squareclamp2 years ago

    awesome, thanks!

  • default discord avatar
    techinvertedlast year

    hey

    @364124941832159242

    , any update on open sourcing the search implementation

  • discord user avatar
    jmikrut
    last year

    hey! honestly i haven't thought about this in a minute but maybe we can expedite this for you

  • default discord avatar
    techinvertedlast year

    Hey

    @364124941832159242

    , would really appreciate that. Thanks

    :welcomehat:
  • default discord avatar
    lucaceck9512 months ago

    Hi everyone


    any updates for searching words in slate richtext?

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.