Проблем при търсене в база данни...

Msecurity

Registered
Здравейте,
има ли вариант да търся и думи в множествено число в базата данни, например: имам "Фризьорски салон" ... но когато влезе потребителя и напише в търсачката "Фризьорски салони" пак да излизат и резултатите който съдържат само "Фризьорски салон" .. изпробвах сигурно 100 начина и нищо няма ефект :(
Някои сблъсквал ли се е с подобен проблем?
 
Msecurity каза:
Здравейте,
има ли вариант да търся и думи в множествено число в базата данни, например: имам "Фризьорски салон" ... но когато влезе потребителя и напише в търсачката "Фризьорски салони" пак да излизат и резултатите който съдържат само "Фризьорски салон" .. изпробвах сигурно 100 начина и нищо няма ефект :(
Някои сблъсквал ли се е с подобен проблем?
Ако стринговете са ти на български само то можеш да разбиваш и тримваш съдържанието на стринга. Множественото число изобщо не е лесен за решаване проблем. Виждал съм набор от класове занимаващи се само с обработката на входящият стринг за търсене в единствено и множествено число. Абе едно лесно решение ще ти дам но не е всеобхватно естествено.
PHP:
<?php
$searchString = "Фризьорски салони";
$searchStringArray = explode(" ", $searchString);

$plural = ["и", "я", "е"];

$search = "";
foreach ($searchStringArray as $string) {
	$string = trim($string);
	$lastChar = mb_substr($string, -1);
	if (in_array($lastChar, $plural)) {
		$search .= rtrim($string, $lastChar)." ";
	}
}
print $search;
 
Поиграх си малко над проблема и драснах еднин клас, но не обхваща всички ситуации а само част от основните положения в Българският език. Има много изключения, но е нещо над което да поразмишляваш!

PHP:
<?php
class Noun
{
	private $plural = ["и", "я", "е", "има", "ина", "ини", "ове"];
	
	public function __construct()
	{
		
	}
	
	public function isPlural($string)
	{	
		$stringArray = explode(" ", $string);
		$array = [];
		foreach ($stringArray as $word) {
			$word = preg_replace("/[^а-яa-z]/iu", "", $word);
			switch (mb_strlen($word)) {
				case 1 : 
				case 2 : 
				case 3 :
					$array[] = [
						"plural" => false,
						"word" => $word 
					];
					break;
				case 4 :
					$lastChar = $this->getPart($word, -1, mb_strlen($word));
					if (in_array($lastChar, $this->plural)) {
						$array[] = [
							"plural" => true,
							"word" => $word 
						];
					} else {
						$array[] = [
							"plural" => false,
							"word" => $word 
						];
					}
					break;
				default :
					$lastChar = $this->getPart($word, -1, mb_strlen($word));
					if (in_array($lastChar, $this->plural)) {
						$array[] = [
							"plural" => true,
							"word" => $word 
						];
					} else {
						$part = $this->getPart($word, -3, mb_strlen($word));
						if (in_array($part, $this->plural)) {
							$array[] = [
								"plural" => true,
								"word" => $word 
							];
						} else {
							$array[] = [
								"plural" => false,
								"word" => $word 
							];
						}
					}
			}
		}
		return $array;
	}
	
	private function getPart($string, $start = 0, $end = 0)
	{
		return mb_substr($string, $start, $end);
	}
}

$searchString = "Фризьорските салони на Жоро Ножицата са много и в тях винаги има балсам и кърпи за коса.";
$noun = new Noun;
print "<pre>";
foreach ($noun->isPlural($searchString) as $array) {
	if ($array["plural"]){
		print $array["word"]." ";
	}
}
 
Това ми се струва направо абсурдна задача. Ето няколко примера:

карти, пръсти => карт, пръст; или карта, пръста? Не можеш еднозначно да определиш

фъстъци, звънци, летци => фъстък, звънк, летк; или фъстъец, звънец, летец? Айде, тук може би можеш да проверяваш дали предишната буква е гласна/съгласна

Да вземем мн. число на "-та":
прасета, джуджета, лопата, врата, карта => прасе, джудже, лопа, вра, кар? Няма фиксирано правило, че дума, завършваща на -та, е в мн. число. А какво остава за членуването - храната/перата/чинията....

телефони, грамофони, пилони, стени, храни
1. телефон, грамофон, пилон, стен, хран
или 2. телефона, грамофона, пилона, стена, храна?
Поредната ситуация, в която без речник просто няма как да се оправиш.

По-добре вместо да се занимаваш с това, използвай fuzzy search и не се опитвай да разбиеш българската граматика на конкретни правила. Изключенията са твърде много.
 
anonimen каза:
Това ми се струва направо абсурдна задача. Ето няколко примера:

карти, пръсти => карт, пръст; или карта, пръста? Не можеш еднозначно да определиш

фъстъци, звънци, летци => фъстък, звънк, летк; или фъстъец, звънец, летец? Айде, тук може би можеш да проверяваш дали предишната буква е гласна/съгласна

Да вземем мн. число на "-та":
прасета, джуджета, лопата, врата, карта => прасе, джудже, лопа, вра, кар? Няма фиксирано правило, че дума, завършваща на -та, е в мн. число. А какво остава за членуването - храната/перата/чинията....

телефони, грамофони, пилони, стени, храни
1. телефон, грамофон, пилон, стен, хран
или 2. телефона, грамофона, пилона, стена, храна?
Поредната ситуация, в която без речник просто няма как да се оправиш.

По-добре вместо да се занимаваш с това, използвай fuzzy search и не се опитвай да разбиеш българската граматика на конкретни правила. Изключенията са твърде много.

Повече от съгласен съм, но както казвам съм виждал проект базиран на подобна логика. Пред време пък един приятел си създаде речник с множествените числа привеждайки ги и в единствено число. Просто решението, като цяло е трудоемко. Аз бих решил проблема, чрез целево разбиване на многочлени, но това би връщало изключително неточни фрази от търсенето. Просто си трябва стабилно обработване на входящият низ, за да се определя конкретиката на търсените фрази.
 
Това което искате да направите май се нарича stemming, превръщане на думата в някаква базова форма.

http://lml.bas.bg/~na__________kov/bulstem/
махни подчертавките

в github също се намират няколко решения...
 
djman каза:
Това което искате да направите май се нарича stemming, превръщане на думата в някаква базова форма.

http://lml.bas.bg/~na__________kov/bulstem/
махни подчертавките

в github също се намират няколко решения...

Аз дадох един опростен варянт, но има и граматични библиотеки, които описват и променят формите на базови думи. Наистина има много сложни и доста всеобхватни решения на основните проблеми, но да кажем, че дадох едно решение, което може да върне част от резултатите. Даже съм виждал, как на думи с дължина по-голяма примерно от 5 символа се режат последните 3/4 букви и се подават за издирване в базата. Примерно
Фризьорски -> става -> Фризьор но както казах много зависи от това, какво се очаква да се търси във въпросната база и да се знае как да се обработва входящият низ, така че да се конкретизира търсенето.
 
Колегата правилно те е препратил към stemmer. В github има имплементации на стемъра от линка, пазиш базовата дума в БД, после търсиш по базовата.
 

Горе