Поиск строки поля Solr со специальными символами - PullRequest
0 голосов
/ 01 июня 2018

Я только начал работать над Solr.Есть поле телефона, и оно было определено в схеме, как показано ниже

<field docValues="true" indexed="true" multiValued="true" name="phones" stored="true" type="StrField"/>

Насколько я понимаю, строковое поле будет пытаться выполнить точное совпадение, но пользователь может использовать любой формат для поиска номера телефона с помощью специальногосимволы, такие как (111) 111-1111.Поэтому я использовал ClientUtils.escapeQueryChars, чтобы добавить косую черту для специальных символов, но поиск не дал никакого результата.Я пытался понять, почему и есть ли критерии, по которым специальные символы нельзя экранировать для строкового поля?Я не думаю, что токенизатор имеет значение, так как это строковое поле, и я использую edismax parser.Есть идеи?

1 Ответ

0 голосов
/ 02 июня 2018

Использование Solr 7.3.1 Я воспроизвел то, что вы просили, и могу подтвердить, что, если вы правильно выберете (, ) и , вы получите нужные вам хиты.

Схема

  • id: строка
  • телефоны: строка (многозначные, значения документов, индексированные, сохраненные)

Документы

{
  "id":"doc1",
  "phones":["(111) 111-1111"],
  "_version_":1602190176246824960
},
{
  "id":"doc2",
  "phones":["111 111-1111"],
  "_version_":1602190397829808128
},
{
  "id":"doc3",
  "phones":["111 (111)-1111"],
  "_version_":1602190400002457600
}

Запрос

/select?q=phones:\(111\)\ 111-1111

{
    "id":"doc1",
    "phones":["(111) 111-1111"],
    "_version_":1602190176246824960}]
}

/select?debugQuery=on&q=phones:111\ 111-1111

{
    "id":"doc2",
    "phones":["111 111-1111"],
    "_version_":1602190397829808128}]
}

/select?debugQuery=on&q=phones:1111111111

"response":{"numFound":0,"start":0,"docs":[]}

Поведение точно такое, как описано - только точные совпадения.

Получение желаемого поведения с помощью PatternReplaceCharFilterFactory

Давайте создадим пользовательский тип поля, который удаляет все, что не является цифрой или буквой:

curl -X POST -H 'Content-type:application/json' --data-binary '{
  "add-field-type" : {
     "name":"phoneStripped",
     "class":"solr.TextField",
     "positionIncrementGap":"100",
     "analyzer" : {
        "charFilters":[{
           "class":"solr.PatternReplaceCharFilterFactory",
           "replacement":"",
           "pattern":"[^a-zA-Z0-9]"
        }],
        "tokenizer":{
           "class":"solr.KeywordTokenizerFactory" 
        },
     }
  }
}' http://localhost:8983/solr/foo/schema

Затем мы создаемновое поле с именем phone_stripped, используя этот новый тип поля (вы можете сделать это в пользовательском интерфейсе), и переиндексируйте наши документы - теперь используя новое имя поля:

  {
    "id":"doc1",
    "phone_stripped":"(111) 111-1111"
  },
  {
    "id":"doc3",
    "phone_stripped":"111 (111)-1111"
  },
  {
    "id":"doc2",
    "phone_stripped":"111 111-1111"
  }

И затем мы ищем просто 1111111111:

"response":{"numFound":3,"start":0,"docs":[ .. all our docs ..]

Использование предыдущего поискаh, phone_stripped:\(111\)\ 111-1111:

"response":{"numFound":3,"start":0,"docs":[ .. all our docs ..]

И просто чтобы убедиться, что мы не сломали вещи невероятным образом, давайте поищем phone_stripped:\(111\)\ 111-1112:

"response":{"numFound":0,"start":0,"docs":[]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...