2014-08-29 1 views
1

Je travaille sur un filtre de produit pour notre site Web et j'ai rencontré quelques difficultés concernant l'utilisation de "facet.missing = true".Problème avec une requête de facette négative en utilisant solr pour la valeur manquante

Je sais que je suis censé utiliser un filtre de requête comme "fq = -facetField: [* TO *]" pour filtrer les résultats aux produits avec ce champ manquant.

J'ai construit une aide de filtre global pour mon application qui construit le paramètre fq dynamiquement pour toutes les requêtes pour éviter tout de manquer sur les filtres en fonction d'autorisation de l'utilisateur qui ressemble essentiellement comme celui-ci (php):

$params['fq'] = sprintf('((%s) AND (%s))', $custom, $system); 

où système $ est le filtre à base globale la permission, ce qui pourrait ressembler à (non réelle mais similaire):

(isdiscontinued:0 AND ishidden:0 AND contract:3) 

personnalisé $ contient le filtre réelle recherche, l'utilisateur construit via l'interface utilisateur. Supposons que le filtre bluetooth du portable porte le nom fq_bluetooth avec des valeurs: Non, Oui ou la valeur est manquante. Cela rendrait le look fq finale comme:

((-fq_bluetooth:[* TO *]) AND ((isdiscontinued:0 AND ishidden:0 AND contract:3))) 

Cependant retourne 0 produits pour la requête que je vous envoie pour cette catégorie.

Si je modifie la requête de filtre:

((fq_bluetooth:[* TO *]) AND ((isdiscontinued:0 AND ishidden:0 AND contract:3))) 

Puis-je obtenir le résultat pourrait attendre des comtes de Oui + Non, sans tenir compte du non précisé.

Comment dois-je formater la requête de filtre pour que cela fonctionne correctement?

[modifier]

Je pourrais aussi vouloir combiner les facettes et peut-être filtrer seulement produits sans Bluetooth ou ceux où Bluetooth n'est pas spécifiée. Alors peut-être comme celui-ci (ce qui bien sûr ne fonctionne pas non plus):

((-fq_bluetooth:[* TO *] OR fq_bluetooth:"No") AND ((isdiscontinued:0 AND ishidden:0 AND contract:3))) 

Je remarque avec debugQuery, je vois une requête de filtre comme:

fq_bluetooth:("No" OR -[* TO *]) 

être analysé comme:

fq_bluetooth:No -fq_bluetooth:[* TO *] 

Je ne vois pas l'OR dans la requête analysée - et de mes recherches les requêtes de paramètres fq ne respectent pas l'opérateur OR (??).

Peut-être que l'OR fonctionne, mais comme la requête négative semble échouer par elle-même, c'est peut-être pourquoi je ne peux pas voir le fonctionnement de l'OR lorsqu'il est combiné comme ça.

Répondre

4

Supprimez les parenthèses inutiles et divisez votre requête de filtre en deux requêtes de filtre, l'une pour les restrictions système et l'autre pour le filtrage généré par l'utilisateur.

1) Puisque vous voulez satisfaire à deux exigences logiques dans votre requête (restrictions de sécurité et filtrage généré par l'utilisateur), pourquoi ne pas réécrire votre requête avec deux requêtes de filtre?

Un système d'autorisation, l'autre pour les requêtes générées à partir de votre interface d'application (échappements omis):

... fq = isdiscontinued: 0 ET IsHidden: 0 ET contrat: 3 & fq = -fq_bluetooth : [* a *]

Cela va même aider à filter query caching

2) en ce qui concerne votre problème de requête spécifique, en expérimentant, il semble que la présence de parenthèses est en train de changer les résultats escomptés. Faire des tests avec une instance locale, je suit, si j'utilise votre syntaxe, ((-ProcedeImageElectronique:[* TO *]) AND (Pays:France AND GrandeCategorie:FILM)) renvoie 0 résultats:

{ 
    "responseHeader": { 
    "status": 0, 
    "QTime": 1, 
    "params": { 
     "facet": "off", 
     "indent": "true", 
     "q": "*:*", 
     "wt": "json", 
     "fq": "((-ProcedeImageElectronique:[* TO *]) AND (Pays:France AND GrandeCategorie:FILM))" 
    } 
    }, 
    "response": { 
    "numFound": 0, 
    "start": 0, 
    "maxScore": 0, 
    "docs": [] 
    } 
} 

Versus -ProcedeImageElectronique:[* TO *] AND Pays:France AND GrandeCategorie:FILM qui se traduit par le comportement attendu:

{ 
    "responseHeader": { 
    "status": 0, 
    "QTime": 1, 
    "params": { 
     "facet": "off", 
     "indent": "true", 
     "q": "*:*", 
     "wt": "json", 
     "fq": "-ProcedeImageElectronique:[* TO *] AND Pays:France AND GrandeCategorie:FILM" 
    } 
    }, 
    "response": { 
    "numFound": 1733, 
    "start": 0, 
    "maxScore": 1, 
    "docs": [...] 
    } 
} 

De même, en utilisant deux requêtes de filtrage renvoie le résultat attendu:

{ 
    "responseHeader": { 
    "status": 0, 
    "QTime": 0, 
    "params": { 
     "facet": "off", 
     "indent": "true", 
     "q": "*:*", 
     "wt": "json", 
     "fq": [ 
     "-ProcedeImageElectronique:[* TO *]", 
     "GrandeCategorie:FILM AND Pays:France" 
     ] 
    } 
    }, 
    "response": { 
    "numFound": 1733, 
    "start": 0, 
    "maxScore": 1, 
    "docs": [...] 
    } 
} 

EDIT: this post explique clairement pourquoi l'utilisation entre parenthèses peut conduire à unex résultats pectés. Pour citer:

Si le BoolenQuery de niveau supérieur contient quelque part à l'intérieur de celui-ci un imbriqué BooleanQuery qui ne contient que des clauses niées, cette requête imbriquée ne sera pas modifié, et (par définition) An't correspondent à aucun document - si cela est requis, cela signifie que la requête externe ne correspondra pas.

+0

Merci pour la réponse! Qux de J'avais réussi à tenter que faire ma requête comme: fq = -fq_bluetooth: [* A *] & FQ = (isdiscontinued: 0 ET IsHidden: 0 ET contrat: 3) (BTW, il y a plus au filtre du système, y compris plusieurs groupes et Éléments ORed). Bien que la requête a travaillé, il échouerait quand je voulais ajouter plusieurs conditions: fq = fq_bluetooth :("Non" OU - [* A *]) & FQ = (isdiscontinued: 0 ET IsHidden: 0 ET contrat: 3) – Chris

+0

Avez-vous essayé sans parenteshis? dire fq = fq_bluetooth: "Non" OU - [* A *] – qux

+0

Le problème est la clause niée. Essayez comme ceci: 'fq = fq_bluetooth: Non OU (-fq_bluetooth: [* A *] *: *)' Cela fonctionne pour moi. Donc, chaque fois que vous voulez faire correspondre des valeurs manquantes, utilisez '(-fieldname: [* TO *] *: *)' dans le générateur de requêtes de votre application – qux

Questions connexes