Question

J'espérais mettre en œuvre une recherche de texte facile, mais efficace pour App Engine que je pouvais utiliser jusqu'à ce que les capacités de recherche de texte officiel pour le moteur d'application sont libérés. Je vois qu'il ya des bibliothèques là-bas, mais est toujours embêtant pour installer quelque chose de nouveau. Je me demande si cela est une stratégie valide:

1) Casser chaque propriété qui doit être une recherche textuelle dans un ensemble (liste) des fragments de texte 2) Conserver la fiche avec ces listes ajoutées 3) Lors de la recherche, il suffit d'utiliser les filtres d'égalité sur les propriétés de la liste

Par exemple, si j'avais un dossier:

{
  firstName="Jon";
  lastName="Doe";
}

Je pourrais enregistrer une propriété comme ceci:

{
  firstName="Jon";
  lastName="Doe";

  // not case sensative:
  firstNameSearchable=["j","o", "n","jo","on","jon"];   
  lastNameSerachable=["D","o","e","do","oe","doe"];
}

Alors à la recherche, je pouvais le faire et attendre de retourner le dossier ci-dessus:

//pseudo-code:
SELECT person 
WHERE firstNameSearchable=="jo" AND
      lastNameSearchable=="oe"

Est-ce recherches texte comment sont mises en œuvre? Comment gardez-vous l'indice de sortir du contrôle, surtout si vous avez un paragraphe ou quelque chose? Y at-il une autre stratégie de compression qui est habituellement utilisé? Je suppose que si je veux juste quelque chose simple, ce travail pourrait, mais il est agréable de connaître les problèmes que je pourrais rencontrer.

Mise à jour :::

Ok, donc il se trouve ce concept est sans doute légitime. Ce blog fait aussi référence à ce: http: / /googleappengine.blogspot.com/2010/04/making-your-app-searchable-using-self.html

Note: le code source dans le blog ci-dessus ne fonctionne pas avec la version actuelle de Lucene. J'ai installé l'ancienne version (2.9.3) comme une solution rapide puisque Google est censé sortir avec leur propre recherche de texte pour le moteur d'application assez vite de toute façon.

La solution proposée dans la réponse ci-dessous est une belle solution rapide, mais en raison des limitations de grande table, ne fonctionne que si vous interrogez sur un champ parce que vous ne pouvez utiliser que les opérateurs non-égalité sur une propriété dans une requête:

db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2", "abc", u"abc" + u"\ufffd")

Si vous souhaitez interroger sur plus d'une propriété, vous pouvez enregistrer des index pour chaque propriété. Dans mon cas, j'utilise cela pour une auto-suggérer des fonctionnalités sur les petits champs de texte, la recherche ne fait des correspondances de mots et de phrases dans un document (vous pouvez utiliser la mise en œuvre du blog ci-dessus pour cela). Il se trouve que c'est assez simple et je ne vraiment pas besoin d'une bibliothèque pour elle. De plus, je prévois que si quelqu'un est à la recherche de « Larry » ils vont commencer en tapant « La ... » au lieu de commencer au milieu du mot: « Arry ». Donc, si la propriété est l'indice ne dispose que pour le nom ou quelque chose d'une personne similaire, les sous-chaînes commençant par la première lettre, si l'indice « Larry » serait juste { « l », « la », « lar », « larr », "larry"}

Je l'ai fait quelque chose de différent pour les données comme les numéros de téléphone où vous souhaitez rechercher un à partir du début ou chiffres du milieu. Dans ce cas, je viens emmagasinés l'ensemble des sous-chaînes commençant par les chaînes de longueur 3, de sorte que le numéro de téléphone « 123-456-7890 » serait: { « 123 », « 234 », « 345 », .... . "123456789", "234567890", "1234567890"}, un total de (10 * ((10 + 1) / 2)) - (10 + 9) = 41 indices ... en fait ce que je faisais était un peu plus complexe afin d'éliminer certains peu probables à être utilisés sous-chaînes, mais vous voyez l'idée.

Ensuite, votre requête serait: (Code Pseaudo) SELECT * de personne WHERE firstNameSearchIndex de la "LAR" phonenumberSearchIndex == "1234"

La façon dont fonctionne le moteur d'application est que si les sous-chaînes de requête correspondent à l'une des sous-chaînes dans la propriété, qui est considéré comme un match.

Était-ce utile?

La solution

Dans la pratique, ce ne sera pas l'échelle. Pour une chaîne de caractères n, vous avez besoin n entrées d'index factorielles. Une chaîne de caractères 500 aurait besoin de 1,2 * 10 ^ 1134 index pour capturer tous les sous-chaînes possibles. Vous allez mourir de vieillesse avant la fin de votre entité d'écriture sur le datastore.

comme Implémentations search.SearchableModel créer une entrée d'index par mot, ce qui est un peu plus réaliste. Vous ne pouvez pas rechercher des sous-chaînes arbitraires, mais il y a un truc qui vous permet de matcher préfixes:

De les docs :

  

db.GqlQuery ( "SELECT * FROM MyModel   Où prop> = 1 ET prop <: 2" ,   "Abc", u "abc" + u "\ uFFFD")

     

correspond à chaque entité MyModel avec   un accessoire de propriété de chaîne qui commence   avec les caractères abc. le unicode   chaîne u « \ uFFFD » représente le   le plus grand caractère Unicode possible.   Lorsque les valeurs de propriété sont classés en   un indice, les valeurs qui tombent dans cette   gamme sont toutes les valeurs qui commencent   avec le préfixe donné.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top