2011-08-10 9 views
10

Tengo una entidad llamada lastName con el valor "Benjamin". ¿Hay alguna manera en objectify que si el usuario pone "Ben" o "jam" o "Benja". Todavía puedo encontrar esta entidad usando query.filter(). Debo usar la consulta ya que hay otros criterios de búsqueda iam checking.Buscar subcadena dentro de una entidad usando objectify

Vi algo en "Obgaektify" llamado operador "starts with". Pero no está funcionando. Cualquier sugerencia sera apreciada. Gracias

+1

¿Por qué querrías hacer una búsqueda de subcadena dentro de los nombres? Nunca he visto un buen caso de uso para esto. –

+0

No está dentro de los nombres en acto. Está dentro de la búsqueda de texto en general. pero por simplicidad solo dije el nombre :) –

+3

Bueno, la pregunta permanecía. La búsqueda de texto completo deriva y normaliza, luego busca palabras completas, porque no tiene mucho sentido que una consulta para 'gato' devuelva 'defecar'. –

Respuesta

12

no hay "así como" para consultas de tipo sub-cadena, sin embargo, un mayúsculas y minúsculas "comienza con" podría ser simulado mediante la adopción de advantag e de los operadores > y < en los índices.

// The start string 
String searchStr = "Ben"; 

// emulate a "starts with" query 
Query q = new Query("MyEntity") 
q.addFilter("name", Query.FilterOperator.GREATER_THAN_OR_EQUAL, searchStr); 
q.addFilter("name", Query.FilterOperator.LESS_THAN, searchStr + "\ufffd"); 

La consulta 'buscar' la propiedad name para los artículos que empiezan con "Ben", y están a menos de "Ben\ufffd", donde \ufffd es la más alta posible de caracteres Unicode.

+0

'u '\ ufffd' es el 'carácter UTF más grande' canónico que se utiliza aquí. –

+0

Esto funcionó para mí. Gracias por su ayuda :) –

+0

Cool Shady, acepte la respuesta marcando la marca verde, esto le da 2rep, rep al propietario de la respuesta e indica a los demás que la pregunta está resuelta. –

2

No existe un índice estándar existente para consultas con contenido similar. Por cierto, siempre puedes presentar el tuyo. En este caso se puede hacer:

  1. complemento y el campo sintético como el método de String[] lastNameIndex
  2. complemento marcado como @PrePersist que llenará lastNameIndex campo con todas las combinaciones disponibles
  3. Cuando usted quiere encontrar entidades utilizando este índice hacer query.filter('lastNameIndex =', val)
0

Poner la respuesta de Chris y el comentario de Nick juntos, aquí está el código para construir un filtro de consulta para Objectify V4:

public <T> Query<T> fieldStartsWith(Query<T> query, String field, String search){ 
    query = query.filter(field + " >=", search); 
    return query.filter(field + " <", searchStr+"\ufffd"); 
} 
+0

Creo que debería ser '<" \ ufffd "' y no '<=' porque FFFD no es un carácter ASCII imprimible, por lo que querría excluirlo. En la práctica, probablemente no importará, sin embargo. Corrígeme si estoy equivocado. –

+0

Gracias Oliver, tienes razón. ¡Modifiqué mi respuesta! – Zensursula

0

He utilizado el método tokenización. Aquí está el código en Java:

private String tokenize(String phrase) { 
StringBuilder tokens = new StringBuilder(); 
try { 
    for (String word : phrase.split(" ")) { 
    if (word.length() < 1) { 
     continue; 
    } 
    int j = 1; 
    while (true) { 
     for (int i = 0; i < word.length() - j + 1; i++) { 
     tokens.append(word.substring(i, i + j)).append(" "); 
     } 
     if (j == word.length()) { 
     break; 
     } 
     j++; 
    } 
    } 
} catch (Throwable t) { 
    t.printStackTrace(); 
} 
return tokens.toString();} 

Esto permite definir un campo indexable, a continuación, procesar consultas estándar de Y y SearchService.

Cuestiones relacionadas