1

I have a faunadb collection of users. The data is as follows:

{
    "username": "Hermione Granger",
    "fullName": "Hermione Jean Granger",
    "DOB": "19-September-1979",
    "bloodStatus": "Muggle-Born",
    "gender": "Female",
    "parents": [
      "Wendell Wilkins",
      "Monica Wilkins"
    ]
}

when I use an index I have to search for the whole phrase i.e. Hermione Granger. But I want to search for just Hermione and get the result.

2 Answers 2

1

I came across a solution that seems to work.

The below uses the faunadb client.

"all-items" is an index setup on a collection in Fauna that returns all items in the collection

The lambda is searching on the title field

This will return any document with a title that partially matches the search term.

I know this is a bit late; I hope it helps anyone else who may be looking to do this.

const response = await faunaClient.query(
    q.Map(
        q.Filter(
            q.Paginate(q.Match(q.Index("all_items"))),
            q.Lambda((ref) =>
                q.ContainsStr(
                    q.LowerCase(
                        q.Select(["data", "title"], q.Get(ref))
                    ),
                    title // <= this is your search term
                )
            )
        ),
        q.Lambda((ref) => q.Get(ref))
    )
Sign up to request clarification or add additional context in comments.

Comments

0

The Match function only applies an exact comparison. Partial matches are not supported.

One approach that might work for you is to store fields that would contain multiple values that need to be indexed as arrays.

When you index a field whose value is an array, the index creates multiple index entries for the document so that any one of the array items can be used to match entries. Note that this strategy increases the read and write operations involved.

Here's an example:

> CreateCollection({ name: "u" })
{
  ref: Collection("u"),
  ts: 1618532727920000,
  history_days: 30,
  name: 'u'
}
> Create(Collection("u"), { data: { n: ["Hermione", "Granger"] }})
{
  ref: Ref(Collection("u"), "295985674342892032"),
  ts: 1618532785650000,
  data: { n: [ 'Hermione', 'Granger' ] }
}
> Create(Collection("u"), { data: { n: ["Harry", "Potter"] }})
{
  ref: Ref(Collection("u"), "295985684233060864"),
  ts: 1618532795080000,
  data: { n: [ 'Harry', 'Potter' ] }
}
> Create(Collection("u"), { data: { n: ["Ginny", "Potter"] }})
{
  ref: Ref(Collection("u"), "295985689713967616"),
  ts: 1618532800300000,
  data: { n: [ 'Ginny', 'Potter' ] }
}
> CreateIndex({
  name: "u_by_n",
  source: Collection("u"),
  terms: [
    { field: ["data", "n"] }
  ]
})
{
  ref: Index("u_by_n"),
  ts: 1618533007000000,
  active: true,
  serialized: true,
  name: 'u_by_n3',
  source: Collection("u"),
  terms: [ { field: [ 'data', 'n' ] } ],
  partitions: 1
}
> Paginate(Match(Index("u_by_n"), ["Potter"]))
{
  data: [
    Ref(Collection("u"), "295985684233060864"),
    Ref(Collection("u"), "295985689713967616")
  ]
}

Note that you cannot query for multiple array items in a single field:

> Paginate(Match(Index("u_by_n"), ["Harry", "Potter"]))
{ data: [] }

The reason is that the index has only one field defined in terms, and successful matches require sending an array having the same structure as terms to Match.

To be able to search for the full username and the username as an array, I'd suggest storing both the string and array version of the username field in your documents, e.g. username: 'Hermione Granger' and username_items: ['Hermione', 'Granger']. Then create one index for searching the string field, and another for the array field, then you can search either way,

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.