Как искать частичное совпадение с помощью индекса в fauna db

У меня есть коллекция пользователей faunadb. Данные следующие:

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

когда я использую индекс, мне приходится искать всю фразу, например, Гермиону Грейнджер. Но я хочу найти только Гермиону и получить результат.


person Prabodh    schedule 10.03.2021    source источник


Ответы (1)


Функция Match применяет только точное сравнение. Частичные совпадения не поддерживаются.

Один из подходов, который может сработать для вас, - хранить поля, которые будут содержать несколько значений, которые необходимо проиндексировать как массивы.

Когда вы индексируете поле, значение которого является массивом, индекс создает несколько записей индекса для документа, так что любой из элементов массива может использоваться для сопоставления записей. Обратите внимание, что эта стратегия увеличивает количество операций чтения и записи.

Вот пример:

> 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")
  ]
}

Обратите внимание, что вы не можете запрашивать несколько элементов массива в одном поле:

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

Причина в том, что индекс имеет только одно поле, определенное в terms, и для успешных совпадений требуется отправка массива, имеющего ту же структуру, что и terms, в Match.

Чтобы иметь возможность искать полное имя пользователя и имя пользователя в виде массива, я бы предложил хранить в ваших документах как строку, так и версию массива поля username, например username: 'Hermione Granger' и username_items: ['Hermione', 'Granger']. Затем создайте один индекс для поиска в строковом поле, а другой для поля массива, тогда вы можете искать в любом случае,

person eskwayrd    schedule 16.04.2021