2017-07-29 4 views
0

Comment est-il possible de construire la requête qui va chercher des phrases exactes ainsi que des phrases avec quelques fautes de frappe? Je suis coincé là-dessus et a l'air de bouger dans la mauvaise direction.SOLR eDismax typo tolérance pour les expressions

Par exemple, j'ai champ suivant dans ma requête edismax:

q=apple iphone 

Il fonctionne, mais maintenant je dois le rendre plus tolérant aux fautes de frappe. Je mettre à jour ma requête et maintenant il retourne même résultat qu'avant même lorsque les types d'utilisateurs avec des défauts:

q=aple~2 iphane~2 

Ensuite, je trouve que maintenant la correspondance exacte de la requête est pas toujours sur la première page (par exemple, j'ai vraiment produit ' aple iphane '). Donc, j'ajoute la requête exacte en utilisant la condition 'OU'. Maintenant, ma requête ressemble

q=(aple~2 iphane~2) OR 'aple iphane'^3 

Le problème est, il revient maintenant seul match et ne pas exacte retourne des entrées floues enymore. Qu'est-ce que je fais mal?

Voici requête complète:

http://localhost:8983/solr/test/select?omitHeader=true 
&q=(aple~2 iphane~2) OR 'aple iphane'^3 
&start=0 
&rows=30 
&fl=*,score 
&fq=itemType:"Product" 
&defType=edismax 
&qf=title_de^1000 title_de_ranked^1000 description_de^1 category_name_de^50 brand^15 merchant_name^80 uniuque_values^10000 searchable_attribute_product.name^1000 searchable_attribute_product.description.short^100 searchable_attribute_product.description.long^100 searchable_attribute_mb.book.author^500 
&mm=90 
&pf=title_de^2000 description_de^2 
&ps=1 
&qs=2 
&boost=category_boost 
&mm.autoRelax=true 
&wt=json 
&json.nl=flat 

Dois-je erreur dans la requête, ou la façon dont je choisi est tout à fait tort?

Cette expression que je veux trouver dans 'title_de', tous les autres champs sont secondaires. Ici, il est FieldType de mon schéma:

<fieldType name="text_de_ngram" class="solr.TextField" positionIncrementGap="100"> 
    <analyzer type="index"> 
     <tokenizer class="solr.StandardTokenizerFactory"/> 
     <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_de.txt" /> 
     <filter class="solr.LowerCaseFilterFactory"/> 
     <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/> 
     <filter class="solr.GermanNormalizationFilterFactory"/> 
     <filter class="solr.GermanLightStemFilterFactory"/> 
     <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="25"/> 
    </analyzer> 
    <analyzer type="query"> 
     <tokenizer class="solr.StandardTokenizerFactory"/> 
     <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> 
     <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_de.txt" /> 
     <filter class="solr.LowerCaseFilterFactory"/> 
     <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/> 
     <filter class="solr.GermanNormalizationFilterFactory"/> 
     <filter class="solr.GermanLightStemFilterFactory"/> 
     <filter class="solr.SnowballPorterFilterFactory" language="German" /> 
    </analyzer> 
</fieldType> 

Merci!


UPD: J'ai trouvé ce que ma requête (q = (APLE ~ 2 iphane ~ 2) OR 'aple iphane'^3) était incorrect, donc j'ai trouvé comment construire 2 autres requêtes, qui fonctionne mieux, vous pouvez les voir à la fin de la poste. Je ne sais toujours pas pourquoi ils donnent des résultats différents, car l'opérateur par défaut pour la requête SOLR est 'OU', donc 'term1 OU term2 OU term3 OR term4' devrait être identique à '(term1 OR term2) OR (term3 OR term4).
Comme le suggère @Persimmonium, ajouter quelques exemples de débogage pour montrer ce que les requêtes floues pour les travaux de edismax (mais pas toujours es attendus). J'ai trouvé le 'Apple iPhone' n'est pas le meilleur exemple sur mon grand et l'index de la langue allemande, donc j'ai utilisé le produit avec le nom 'Samsung Magic Info-Lite' comme exemple.

Voici les params pour ma requête:

"params":{ 
     "mm":"100%", 
     "q":"samsung magic", 
     "defType":"edismax", 
     "indent":"on", 
     "qf":"title_de", 
     "fl":"*,score", 
     "pf":"title_de", 
     "wt":"json", 
     "debugQuery":"on", 
     "_":"1501409530601" 
} 

Ainsi, cette requête me retourne bons produits (j'ai 6 produits avec les deux mots ce champ title_de). Après avoir activé les fautes de frappe à deux mots:

"q":"somsung majic" 

Aucun produit se trouvent.

Puis-je ajouter aux deux opérateurs flous mots:

"q":"somsung~2 majic~2" 

6 produits sont trouvés.Voici le résultat debugQuery:

"debug":{ 
     "rawquerystring":"somsung~2 majic~2", 
     "querystring":"somsung~2 majic~2", 
     "parsedquery":"(+(DisjunctionMaxQuery((title_de:somsung~2)) DisjunctionMaxQuery((title_de:majic~2)))~2 DisjunctionMaxQuery((title_de:\"somsung 2 majic 2\")))/no_coord", 
     "parsedquery_toString":"+(((title_de:somsung~2) (title_de:majic~2))~2) (title_de:\"somsung 2 majic 2\")", 
     "explain":{ 
      "69019":"\n1.3424492 = sum of:\n 1.3424492 = sum of:\n 1.1036766 = sum of:\n  0.26367697 = weight(title_de:amsung in 305456) [ClassicSimilarity], result of:\n  0.26367697 = score(doc=305456,freq=1.0), product of:\n   0.073149204 = queryWeight, product of:\n   0.6666666 = boost\n   7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n   0.015219777 = queryNorm\n   3.604646 = fieldWeight in 305456, product of:\n   1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n   7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n   0.5 = fieldNorm(doc=305456)\n  0.2373093 = weight(title_de:msung in 305456) [ClassicSimilarity], result of:\n  0.2373093 = score(doc=305456,freq=1.0), product of:\n   0.06583429 = queryWeight, product of:\n   0.6 = boost\n   7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n   0.015219777 = queryNorm\n   3.604646 = fieldWeight in 305456, product of:\n   1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n   7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n   0.5 = fieldNorm(doc=305456)\n  0.26367697 = weight(title_de:samsun in 305456) [ClassicSimilarity], result of:\n  0.26367697 = score(doc=305456,freq=1.0), product of:\n   0.073149204 = queryWeight, product of:\n   0.6666666 = boost\n   7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n   0.015219777 = queryNorm\n   3.604646 = fieldWeight in 305456, product of:\n   1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n   7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n   0.5 = fieldNorm(doc=305456)\n  0.33901328 = weight(title_de:samsung in 305456) [ClassicSimilarity], result of:\n  0.33901328 = score(doc=305456,freq=1.0), product of:\n   0.094048984 = queryWeight, product of:\n   0.85714287 = boost\n   7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n   0.015219777 = queryNorm\n   3.604646 = fieldWeight in 305456, product of:\n   1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n   7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n   0.5 = fieldNorm(doc=305456)\n 0.23877257 = sum of:\n  0.23877257 = weight(title_de:magic in 305456) [ClassicSimilarity], result of:\n  0.23877257 = score(doc=305456,freq=1.0), product of:\n   0.0762529 = queryWeight, product of:\n   0.8 = boost\n   6.262649 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    1638.0 = docFreq\n    316313.0 = docCount\n   0.015219777 = queryNorm\n   3.1313245 = fieldWeight in 305456, product of:\n   1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n   6.262649 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    1638.0 = docFreq\n    316313.0 = docCount\n   0.5 = fieldNorm(doc=305456)\n", 
     }, 
     "QParser":"ExtendedDismaxQParser" 
} 

Ce comportement me satisfait jusqu'à ce que je n'ai pas produit réel avec le nom « Somsung Majic ». C'est une situation théorique, mais sur la pratique il y a beaucoup d'autres résultats de recherche incorrects causés par ces opérateurs flous.

Donc, pour gérer de telles choses que mon idée était comme je l'ai d'abord d'ajouter l'entrée exacte (sans modificateurs flous) avec le facteur stimulant. Donc, maintenant est la question, comment il sera mis en œuvre mieux. J'ai trouvé, ce que cette requête fonctionne acceptable si je diminue le paramètre mm:

"q":"somsung~2 majic~2 somsung^3 majic^3" 

C'est parce que j'ajouter des mots à interroger, donc « minimum doit correspondre à » besoin d'être aussi diminué. Le problème est que, ce qui diminue de «mm», je reçois de mauvais résultats sur des titres longs avec une entrée de titre exacte (certains mauvais articles pourraient être classés plus haut en raison d'autres facteurs). Ceci est debug pour elle:

"debug":{ 
     "rawquerystring":"somsung~2 majic~2 somsung^3 majic^3", 
     "querystring":"somsung~2 majic~2 somsung^3 majic^3", 
     "parsedquery":"(+(DisjunctionMaxQuery((title_de:somsung~2)) DisjunctionMaxQuery((title_de:majic~2)) DisjunctionMaxQuery((title_de:somsung))^3.0 DisjunctionMaxQuery((title_de:majic))^3.0)~2 DisjunctionMaxQuery((title_de:\"somsung 2 majic 2 somsung 3 majic 3\")))/no_coord", 
     "parsedquery_toString":"+(((title_de:somsung~2) (title_de:majic~2) ((title_de:somsung))^3.0 ((title_de:majic))^3.0)~2) (title_de:\"somsung 2 majic 2 somsung 3 majic 3\")", 
     "explain":{ 
      "69019":"\n0.3418829 = sum of:\n 0.3418829 = product of:\n 0.6837658 = sum of:\n  0.5621489 = sum of:\n  0.13430178 = weight(title_de:amsung in 305456) [ClassicSimilarity], result of:\n   0.13430178 = score(doc=305456,freq=1.0), product of:\n   0.037257966 = queryWeight, product of:\n    0.6666666 = boost\n    7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n    0.0077520725 = queryNorm\n   3.604646 = fieldWeight in 305456, product of:\n    1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n    7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n    0.5 = fieldNorm(doc=305456)\n  0.12087161 = weight(title_de:msung in 305456) [ClassicSimilarity], result of:\n   0.12087161 = score(doc=305456,freq=1.0), product of:\n   0.033532172 = queryWeight, product of:\n    0.6 = boost\n    7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n    0.0077520725 = queryNorm\n   3.604646 = fieldWeight in 305456, product of:\n    1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n    7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n    0.5 = fieldNorm(doc=305456)\n  0.13430178 = weight(title_de:samsun in 305456) [ClassicSimilarity], result of:\n   0.13430178 = score(doc=305456,freq=1.0), product of:\n   0.037257966 = queryWeight, product of:\n    0.6666666 = boost\n    7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n    0.0077520725 = queryNorm\n   3.604646 = fieldWeight in 305456, product of:\n    1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n    7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n    0.5 = fieldNorm(doc=305456)\n  0.17267373 = weight(title_de:samsung in 305456) [ClassicSimilarity], result of:\n   0.17267373 = score(doc=305456,freq=1.0), product of:\n   0.047903106 = queryWeight, product of:\n    0.85714287 = boost\n    7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n    0.0077520725 = queryNorm\n   3.604646 = fieldWeight in 305456, product of:\n    1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n    7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    635.0 = docFreq\n    316313.0 = docCount\n    0.5 = fieldNorm(doc=305456)\n  0.12161691 = sum of:\n  0.12161691 = weight(title_de:magic in 305456) [ClassicSimilarity], result of:\n   0.12161691 = score(doc=305456,freq=1.0), product of:\n   0.038838807 = queryWeight, product of:\n    0.8 = boost\n    6.262649 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    1638.0 = docFreq\n    316313.0 = docCount\n    0.0077520725 = queryNorm\n   3.1313245 = fieldWeight in 305456, product of:\n    1.0 = tf(freq=1.0), with freq of:\n    1.0 = termFreq=1.0\n    6.262649 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n    1638.0 = docFreq\n    316313.0 = docCount\n    0.5 = fieldNorm(doc=305456)\n 0.5 = coord(2/4)\n" 
     }, 
     "QParser":"ExtendedDismaxQParser" 
} 

Cette requête fonctionne même avec grand paramètre 'mm' (ex, 90%):

"q":"(somsung~2 majic~2) OR (somsung^3 majic^3)" 

Mais le problème ici est ce que je reçois 430 (au lieu de 6 voulu). Voici debug l'exemple du mauvais produit:

"debug":{ 
     "rawquerystring":"(somsung~2 majic~2) OR (somsung^3 majic^3)", 
     "querystring":"(somsung~2 majic~2) OR (somsung^3 majic^3)", 
     "parsedquery":"(+((DisjunctionMaxQuery((title_de:somsung~2)) DisjunctionMaxQuery((title_de:majic~2))) (DisjunctionMaxQuery((title_de:somsung))^3.0 DisjunctionMaxQuery((title_de:majic))^3.0))~1 DisjunctionMaxQuery((title_de:\"somsung 2 majic 2 somsung 3 majic 3\")))/no_coord", 
     "parsedquery_toString":"+((((title_de:somsung~2) (title_de:majic~2)) (((title_de:somsung))^3.0 ((title_de:majic))^3.0))~1) (title_de:\"somsung 2 majic 2 somsung 3 majic 3\")", 
     "explain":{ 
      "113746":"\n0.1275867 = sum of:\n 0.1275867 = product of:\n 0.2551734 = sum of:\n  0.2551734 = product of:\n  0.5103468 = sum of:\n   0.5103468 = sum of:\n   0.26860356 = weight(title_de:losung in 296822) [ClassicSimilarity], result of:\n    0.26860356 = score(doc=296822,freq=1.0), product of:\n    0.037257966 = queryWeight, product of:\n     0.6666666 = boost\n     7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n     635.0 = docFreq\n     316313.0 = docCount\n     0.0077520725 = queryNorm\n    7.209292 = fieldWeight in 296822, product of:\n     1.0 = tf(freq=1.0), with freq of:\n     1.0 = termFreq=1.0\n     7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n     635.0 = docFreq\n     316313.0 = docCount\n     1.0 = fieldNorm(doc=296822)\n   0.24174322 = weight(title_de:osung in 296822) [ClassicSimilarity], result of:\n    0.24174322 = score(doc=296822,freq=1.0), product of:\n    0.033532172 = queryWeight, product of:\n     0.6 = boost\n     7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n     635.0 = docFreq\n     316313.0 = docCount\n     0.0077520725 = queryNorm\n    7.209292 = fieldWeight in 296822, product of:\n     1.0 = tf(freq=1.0), with freq of:\n     1.0 = termFreq=1.0\n     7.209292 = idf, computed as log((docCount+1)/(docFreq+1)) + 1 from:\n     635.0 = docFreq\n     316313.0 = docCount\n     1.0 = fieldNorm(doc=296822)\n  0.5 = coord(1/2)\n 0.5 = coord(1/2)\n" 
     }, 
     "QParser":"ExtendedDismaxQParser" 
} 

Alors, même si je suis arrivé de meilleurs résultats je dois encore améliorer la recherche et je ne sais pas encore de quelle manière de choisir et pourquoi j'obtenir de tels résultats.

Répondre

0

Je pense que edismax ne supporte pas l'opérateur ~ floue. Il y a une longue histoire patch here que le développeur a utilisé dans la production depuis longtemps, mais il n'a pas fait dans Solr codebase encore.

+0

Ok, si flou n'est pas pris en charge pour edismax, pourquoi dans ma requête le 'q = aple ~ 2 iphane ~ 2' trouve bons résultats? Est-il interprété comme une requête standard? – Aronsky

+0

utilisez degugQuery = true et découvrons – Persimmonium

+0

J'ai mis à jour la description avec de nouvelles expériences et des résultats de débogage. On dirait qu'Edismax est vraiment capable de fonctionner avec des requêtes floues. Maintenant, je suis confus encore plus qu'avant :) – Aronsky