web-dev-qa-db-fra.com

Requête Solr (q) ou requête de filtre (fq)

J'ai un indice Solr de ~ 1 mil de document produit. J'ai également tout un tas de filtres d'interface utilisateur tels que les catégories, les onglets, les gammes de prix, les tailles, les couleurs et certains autres filtres.

Est-ce la bonne façon d'avoir le q en sélectionnant tout (q=\*:\*) Tandis que tous les autres filtres dans le fq? exemple:

fq=(catid:90 OR catid:81) AND priceEng:[38 TO 40] AND (size:39 OR size:40 OR size:41 OR size:50 OR size:72) AND (colorGroup:Yellow OR colorGroup:Violet OR colorGroup:Orange ... AND (companyId:81 OR companyId:691 OR companyId:671 OR companyId:628 OR companyId:185 OR companyId:602 OR ... AND endShipDays:[* TO 7])

Pour moi, tout, des catégories aux ID d'entreprise, des couleurs et des tailles, etc. ne sont que des filtres. Un problème de performance dans la croissance future avec cette approche? Dois-je mettre certaines des requêtes dans le q, lesquelles?

Merci,

27
Tommy Lord

Dans la mesure du possible, il est préférable d'utiliser Filter Query par rapport à Query normal.

FilterQuery est capable de profiter de FilterCache , ce qui serait un énorme gain de performances par rapport à vos requêtes.

46
Jayendra

Je voudrais regarder les points suivants sur un champ pour décider:

  1. Votre champ a-t-il un score de boost fixe ou avez-vous besoin d'un score pour ce champ? Si oui, mettez-le en requête, car comme mentionné ci-dessus, la requête de filtre n'utilise pas de scores.
  2. La condition de ce champ est-elle fréquemment utilisée? Si oui - encore une fois, comme indiqué précédemment, le cache de filtre peut donner un énorme avantage, mais si non - il peut être encore plus lent.
  3. Votre indice est-il constant? C'est un peu similaire à # 2. Si votre index est mis à jour fréquemment, l'utilisation des requêtes de filtre peut devenir un goulot d'étranglement au lieu de donner une amélioration des performances.

Quelques notes sur # 3: D'après mon expérience, j'avais un gros index qui était rempli de nouveaux documents toutes les quelques secondes et autoSoftCommit était également réglé sur quelques secondes. Pendant les validations logicielles, un nouveau chercheur a été ouvert, ce qui invalidait les caches. Donc, ce qui se passait vraiment, le taux de réussite du filtre était presque toujours de 0. Je peux en dire plus: j'ai compris que la première exécution de requête de filtre est plus coûteuse que l'exécution d'une requête avec toutes ces conditions de filtre déplacées vers "q" au lieu de " fq ". Par exemple, ma requête a pris 1 seconde avec 5 requêtes de filtrage (aucun accès au cache) et 147 ms lorsque j'ai déplacé toutes les conditions "fq" dans la requête principale avec "ET". Mais bien sûr, lorsque j'ai arrêté les mises à jour d'index, les mêmes requêtes de filtre ont pris 0 ms car le cache était utilisé. C'est donc quelque chose à considérer.

Aussi quelques autres points pour votre question:

  • Essayez de ne jamais utiliser de caractères génériques dans votre requête. Cela affecte considérablement les performances. Par conséquent, au lieu de ":" je suggérerais d'utiliser une condition qui est moins constante par demande (la plupart constante par demande qui n'a pas besoin du score que vous voulez mettre à "fq" )
  • Les recherches de plages doivent également être évitées (si possible). Et encore plus de recherches avec des caractères génériques. Il s'agit de vos "endShipDays: [* TO 7]". Par exemple, utiliser "endShipDays: (1 2 3 4 5 6 7)" serait plus efficace, mais ce n'est qu'un exemple, il existe de nombreuses façons.

J'espère que cela aide.

9
Yury K.

La façon dont j'utilise q et fq. J'applique la recherche en texte intégral sur q et tous les filtres sur fq. Disons que vous avez un champ mot-clé que vous allez avoir une recherche en texte intégral avec des champs tels que définis dans votre schéma avec copyField

<copyField source="id" dest="keyword"/>
<copyField source="category" dest="keyword"/>
<copyField source="product_name" dest="keyword"/>
<copyField source="color" dest="keyword"/>
<copyField source="location" dest="keyword"/>
<copyField source="price" dest="keyword"/>
<copyField source="title" dest="keyword"/>
<copyField source="description" dest="keyword"/>

Ma requête ressemblerait

/select?q={keyword}&fq=category:fashion&fq=location:nyc

/select?q=jeans&fq=category:fashion&fq=location:nyc

Comme l'a suggéré digitaljoel, si vous devez interroger plusieurs champs, il serait préférable d'utiliser plusieurs fq (reportez-vous à la requête ci-dessus) au lieu d'utiliser AND et OR avec q =

Remarque: dans mon cas q par défaut se réfère au champ mot-clé tel que défini dans solrconfig.xml

<requestHandler name="/select" class="solr.SearchHandler">
<!-- default values for query parameters can be specified, these
     will be overridden by parameters in the request
  -->
 <lst name="defaults">
   <str name="echoParams">explicit</str>
   <int name="rows">10</int>
   <str name="df">keyword</str>
 </lst>
5
Manjunath Reddy