Conditionals in Query

Hi there,

I’ve got the following query that works nicely (except for an outstanding pagination issue), thanks to the very helpful @ptpaterson .

Map(
    Distinct(
        Map(
            Filter(
                Paginate(
                    Match(
                        Index("search_recipes_cuisine_asc_tag_asc_title_asc")
                    ),
                    { size: 100 }
                ),
                (cuisine, tag, title, ref) =>
                    Or(
                        ContainsStr(
                            Casefold(title),
                            Casefold(searchString)
                        ),
                        ContainsStr(
                            Casefold(tag),
                            Casefold(searchString)
                        ),
                        ContainsStr(
                            Casefold(cuisine),
                            Casefold(searchString)
                        )
                    )
            ),
            (cuisine, tag, title, ref) => ref
        )
    ),
    (ref) => Get(ref)
)

The thing is that I’ve decided to make cuisines and tags optional, which breaks stuff when the above query is run and it comes across a resultant document in the below index where cuisine and/or tag is null.

{
  name: "search_recipes_cuisine_asc_tag_asc_title_asc",
  unique: false,
  serialized: true,
  source: "Recipe",
  values: [
    {
      field: ["data", "cuisines"]
    },
    {
      field: ["data", "tags"]
    },
    {
      field: ["data", "title"]
    },
    {
      field: ["ref"]
    }
  ]
}

While I know that the below query is super wrong, it illustrates what I’m trying to do: Only run the ContainsStr function when the first parameter is not null.

I’ve tried all kinda stuff, but I really don’t know what I’m doing, and I’m not sure this is even possible, so I thought I’d ask the experts here.

Thanks in advance for any advice.

Map(
    Distinct(
        Map(
            Filter(
                Paginate(
                    Match(
                        Index("search_recipes_cuisine_asc_tag_asc_title_asc")
                    ),
                    { size: 100 }
                ),
                (cuisine, tag, title, ref) => {
                    // How to evaluate cuisine and tag (expressions) to do conditionals?
                    if (cuisine && tag ) {  <= always runs
                        return Or(
                            ContainsStr(
                                Casefold(title),
                                Casefold(searchString)
                            ),
                            ContainsStr(
                                Casefold(tag),
                                Casefold(searchString)
                            ),
                            ContainsStr(
                                Casefold(cuisine),
                                Casefold(searchString)
                            )
                        );
                    } else if (cuisine && !tag) { // <= these are never null
                        return Or(
                            ContainsStr(
                                Casefold(title),
                                Casefold(searchString)
                            ),
                            ContainsStr(
                                Casefold(cuisine),
                                Casefold(searchString)
                            )
                        );
                    } else if (!cuisine && tag) { // <= these are never null
                        return Or(
                            ContainsStr(
                                Casefold(title),
                                Casefold(searchString)
                            ),
                            ContainsStr(
                                Casefold(tag),
                                Casefold(searchString)
                            )
                        );
                    } else { // <= never runs
                        return Or(
                            ContainsStr(
                                Casefold(title),
                                Casefold(searchString)
                            )
                        );
                    }
                }
            ),
            (cuisine, tag, title, ref) => ref
        )
    ),
    (ref) => Get(ref)
)

Remember that the javascript arrow function is a convenience – when Map or Filter etc. receive a function argument, they transform it into a Lambda FQL call. Javascript if statements cannot be transformed. You need to use the If FQL function.

But what I am thinking is that since tag and cuisine can be null, you could wrap them in the ToString FQL function. Can you see if that works for you? Strings to Strings are no problem of course, and null is transformed into "null". So, going off your original snippet

Map(
    Distinct(
        Map(
            Filter(
                Paginate(
                    Match(
                        Index("search_recipes_cuisine_asc_tag_asc_title_asc")
                    ),
                    { size: 100 }
                ),
                (cuisine, tag, title, ref) =>
                    Or(
                        ContainsStr(
                            Casefold(title),
                            Casefold(searchString)
                        ),
                        ContainsStr(
                            Casefold(ToString(tag)),
                            Casefold(searchString)
                        ),
                        ContainsStr(
                            Casefold(ToString(cuisine)),
                            Casefold(searchString)
                        )
                    )
            ),
            (cuisine, tag, title, ref) => ref
        )
    ),
    (ref) => Get(ref)
)
1 Like

Hi @ptpaterson.

Thanks for another very helpful response.

I do keep forgetting that I’m in FQL with those convenience functions (they look like Javascript, so I just start typing – derp), so thanks for pointing that out as well.

I was trying stuff like:

ContainsStr(
  Casefold(ToString(cuisine || "")),
  Casefold(searchString)
)

Which was a no go, but ToString() did the trick.

:tada: Awesome!

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.