2012-08-08 8 views
1

Je construis un moteur de recherche de base en utilisant mongodb, j'ai vérifié que la requête de base fonctionne dans le shell mongo. Je ne comprends pas très bien comment cela peut être traduit en PHP.Traduire une requête mongo en php mongo

Les espaces dans la chaîne d'entrée signifient opérateurs 'et' et | ou les caractères de tuyau sont les opérateurs 'ou'. Les modifications de la requête d'entrée, mais pourrait être quelque chose le long de ces lignes (sans les guillemets!):

'o g|ra' 

Ce serait équivalent à l'écriture:

(o&&g)||(ra) 

Basic requête mongo (s'il vous plaît noter que je ne suis pas en essayant de traduire cette requête exacte à chaque fois, j'ai besoin d'être flexible en termes de nombre de $ ands et $ ors). Ont testé et il fonctionne très bien:

db.scores.find({$or:[{Title:/o/i, Title: /g/i},{Title:/ra/i}]) 

Le code que je produis en PHP est la suivante:

if(strstr($textInput, '|') != FALSE) 
{ 
    foreach($orArray as $item) 
    { 
     $itemMod = explode(" " , $item); 
     array_push($stringArray, $itemMod); 
    } 

    $masterAndQueryStack = array(); 

    foreach ($stringArray as $varg) 
    { 
      $multiAndQuerySet = array(); 

      foreach ($varg as $obj) 
      { 
       $searchText = '/'. $obj .'/i'; 
       $regexObj = new MongoRegex($searchText) ; 
       $singleQuery = array('Title' => $regexObj); 
       array_push($multiAndQuerySet , $singleQuery); 
      } 
      array_push($masterAndQueryStack , $multiAndQuerySet); 

    } 

    $orAndQueryStack = array('$or' => $masterAndQueryStack); 
    return $orAndQueryStack ; 
} 

C'est la requête qui a été renvoyée par le code PHP, comme vous pouvez le voir les termes et ont été mis dans un tableau. Je ne vois aucun moyen de les stocker sans les pousser dans un tableau, mais il semble que $ mongodb ou n'aime pas accepter un tableau, je ne suis pas sûr de savoir comment retravailler l'algorithme de recherche pour en tenir compte.

Array 
(
    [$or] => Array 
    (
     [0] => Array 
     ( 
      [0] => Array ([Title] => MongoRegex Object ([regex] => o [flags] => i)) 
      [1] => Array ([Title] => MongoRegex Object ([regex] => g [flags] => i)) 
     ) 
     [1] => Array 
     ( 
      [0] => Array ([Title] => MongoRegex Object ([regex] => ra [flags] => i)) 
     ) 
    ) 
) 
+0

Vous pouvez retourner le premier $ et regex pour utiliser des groupes pour détecter un $ et vous pouvez utiliser l'opérateur $ et réel. – Sammaye

Répondre

2

Pour expliquer mon commentaire plus loin, je vais vous parler de l'$ et l'opérateur: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24and

Vous pouvez imbriquer cela dans votre première $ ou de faire:

Array 
(
    [$or] => Array 
    (
     [0] => Array 
     (
      [$and] => Array 
      ( 
      [0] => Array ([Title] => MongoRegex Object ([regex] => o [flags] => i)) 
      [1] => Array ([Title] => MongoRegex Object ([regex] => g [flags] => i)) 
      ) 
     ) 
     [1] => Array 
     ( 
      [Title] => MongoRegex Object ([regex] => ra [flags] => i) 
     ) 
    ) 
) 

Comme ça. Vous pouvez également effectuer $ et des requêtes dans Regex, quelques informations ici sur la syntaxe regex: http://www.regular-expressions.info/refadv.html

+0

Merci, semble fonctionner correctement avec ce changement. – jjcohen

1

Je ne sais pas quel genre de corpus de données que vous devez rechercher, mais il y a des limites importantes avec votre approche actuelle:

Tous les avertissements ci-dessus peuvent convenir si vous n'avez pas un grand ensemble de données à rechercher.

Quelques alternatives plus performantes seraient:

+0

+1 d'informations importantes à prendre en compte – Sammaye

+0

Merci beaucoup pour ces idées supplémentaires. Ce n'est pas un gros corpus, et l'application semble fonctionner assez rapidement. Malheureusement, la sensibilité à la casse et la génération de tags ne sont pas vraiment des options pour cette implémentation. En ce qui concerne la pertinence et la commande, je prévoyais de faire ce côté client (en utilisant javascript) afin que l'utilisateur puisse réellement spécifier comment ils voient les résultats, cela offre beaucoup plus de flexibilité (pour l'utilisateur) sur le retour. – jjcohen