Разделить и считать
Вы можете разделить строку по фразе и вычесть 1 из числа. Это работает для любой подстроки, что, с другой стороны, означает, что она не учитывает границы слов.
LET things = [
{name: "Here are SomeSome and Some Other Things, brOther!"},
{name: "There are no such substrings in here."},
{name: "some-Other-here-though!"}
]
FOR t IN things
LET Some = LENGTH(SPLIT(t.name, "Some"))-1
LET Other = LENGTH(SPLIT(t.name, "Other"))-1
LET Thing = LENGTH(SPLIT(t.name, "Thing"))-1
RETURN {
Some, Other, Thing
}
Результат:
[
{
"Some": 3,
"Other": 2,
"Thing": 1
},
{
"Some": 0,
"Other": 0,
"Thing": 0
},
{
"Some": 0,
"Other": 1,
"Thing": 0
}
]
Вы можете использовать SPLIT(LOWER(t.name), LOWER("..."))
, чтобы сделать регистр нечувствительный.
СБОР слова
Функцию TOKENS()
можно использовать для разделения ввода на массивы слов, которые затем можно группировать и подсчитывать. Обратите внимание, что я немного изменил ввод. Ввод "SomeSome"
не будет засчитан, потому что "somesome" != "some"
(этот вариант основан на слове, а не на подстроке).
LET things = [
{name: "Here are SOME some and Some Other Things. More Other!"},
{name: "There are no such substrings in here."},
{name: "some-Other-here-though!"}
]
LET whitelist = TOKENS("Some Other Things", "text_en")
FOR t IN things
LET whitelisted = (FOR w IN TOKENS(t.name, "text_en") FILTER w IN whitelist RETURN w)
LET counts = MERGE(FOR w IN whitelisted
COLLECT word = w WITH COUNT INTO count
RETURN { [word]: count }
)
RETURN {
name: t.name,
some: counts.some || 0,
other: counts.other || 0,
things: counts.things ||0
}
Результат:
[
{
"name": "Here are SOME some and Some Other Things. More Other!",
"some": 3,
"other": 2,
"things": 0
},
{
"name": "There are no such substrings in here.",
"some": 0,
"other": 0,
"things": 0
},
{
"name": "some-Other-here-though!",
"some": 1,
"other": 1,
"things": 0
}
]
Это использует подзапрос для COLLECT, в противном случае он будет считать общее количество вхождений для всего ввода.
Шаг белого списка не является строго необходимым, вы также можете позволить ему подсчитать все слова. Для больших входных строк это может сэкономить некоторую память, чтобы не делать этого для слов, которые вас не интересуют в любом случае.
Возможно, вы захотите создать отдельный Анализатор с отключенным основанием для языка, если вы хочу точно подобрать слова. Вы также можете отключить нормализация ("accent": true, "case": "none"
). В качестве альтернативы можно использовать REGEX_SPLIT()
для типичных пробельных символов и знаков препинания для более простого токенизации, но это зависит от вашего варианта использования.
Другие решения
Не знаю Не думаю, что можно подсчитать каждый входной объект независимо с помощью COLLECT без подзапроса, если только вам не нужен общий счет.
Разделение - это немного хак, но вы можете заменить SPLIT () на REGEX_SPLIT () и Оберните поисковые фразы в \b
, чтобы они совпадали только в том случае, если границы слов находятся с обеих сторон. Тогда он должен соответствовать только словам (более или менее):
LET things = [
{name: "Here are SomeSome and Some Other Things, brOther!"},
{name: "There are no such substrings in here."},
{name: "some-Other-here-though!"}
]
FOR t IN things
LET Some = LENGTH(REGEX_SPLIT(t.name, "\\bSome\\b"))-1
LET Other = LENGTH(REGEX_SPLIT(t.name, "\\bOther\\b"))-1
LET Thing = LENGTH(REGEX_SPLIT(t.name, "\\bThings\\b"))-1
RETURN {
Some, Other, Thing
}
Результат:
[
{
"Some": 1,
"Other": 1,
"Thing": 1
},
{
"Some": 0,
"Other": 0,
"Thing": 0
},
{
"Some": 0,
"Other": 1,
"Thing": 0
}
]
Более элегантным решением будет использование ArangoSearch для подсчета слов, но это не так есть функция, позволяющая вам узнать, как часто слово встречается. Он может отслеживать это уже внутри (функция анализатора «частота» ), но на данный момент он определенно не отображается.