2015-04-17 3 views
3

J'ai un champ de contenu (chaîne) indexé dans elasticsearch. L 'analyseur est un analyseur standard par défaut.Comment faire correspondre les termes avec des espaces dans elasticsearch?

Lorsque j'utilise la requête de correspondance pour la recherche:

{"query":{"match":{"content":"micro soft", "operator":"and"}}} 

résultat montre qu'il ne peut pas correspondre à "Microsoft".

Ensuite, comment utiliser le mot-clé d'entrée "micro soft" pour faire correspondre le contenu du document contient "microsoft"?

Répondre

0

Essayez cette ES wilcard comme ci-dessous

{ 
"query" : { 
    "bool" : { 
     "must" : { 
      "wildcard" : { "content":"micro*soft" } 
     } 
    } 
} 

} 
1

Une autre solution consiste à utiliser le filtre jeton nGram , qui vous permettra d'avoir un match de plus « floue ».

En utilisant votre exemple pour « microsoft » et « micro soft », voici un exemple de la façon dont le filtre jeton un ngram renversera les jetons:

POST /test 
{ 
    "settings": { 
    "analysis": { 
     "filter": { 
     "my_ngrams": { 
      "type": "ngram", 
      "min_gram": "3", 
      "max_gram": "5" 
     } 
     }, 
     "analyzer" : { 
     "my_analyzer" : { 
      "type" : "custom", 
      "tokenizer" : "standard", 
      "filter": ["my_ngrams"] 
     } 
     } 
    } 
    }, 
    "mappings": { 
    "doc": { 
     "properties": { 
     "body": { 
      "type": "string", 
      "analyzer": "my_analyzer" 
     } 
     } 
    } 
    } 
} 

et l'analyse des deux choses:

curl '0:9200/test/_analyze?field=body&pretty' -d'microsoft' 
{ 
    "tokens" : [ { 
    "token" : "mic" 
    }, { 
    "token" : "micr" 
    }, { 
    "token" : "micro" 
    }, { 
    "token" : "icr" 
    }, { 
    "token" : "icro" 
    }, { 
    "token" : "icros" 
    }, { 
    "token" : "cro" 
    }, { 
    "token" : "cros" 
    }, { 
    "token" : "croso" 
    }, { 
    "token" : "ros" 
    }, { 
    "token" : "roso" 
    }, { 
    "token" : "rosof" 
    }, { 
    "token" : "oso" 
    }, { 
    "token" : "osof" 
    }, { 
    "token" : "osoft" 
    }, { 
    "token" : "sof" 
    }, { 
    "token" : "soft" 
    }, { 
    "token" : "oft" 
    } ] 
} 

curl '0:9200/test/_analyze?field=body&pretty' -d'micro soft' 
{ 
    "tokens" : [ { 
    "token" : "mic" 
    }, { 
    "token" : "micr" 
    }, { 
    "token" : "micro" 
    }, { 
    "token" : "icr" 
    }, { 
    "token" : "icro" 
    }, { 
    "token" : "cro" 
    }, { 
    "token" : "sof" 
    }, { 
    "token" : "soft" 
    }, { 
    "token" : "oft" 
    } ] 
} 

(je coupe une partie de la sortie, la sortie complète ici: https://gist.github.com/dakrone/10abb4a0cfe8ce8636ad)

Comme vous pouvez le voir, depuis le ngram termes pour "microsoft" et "micro soft" chevauchement, vous serez en mesure de trouver des correspondances pour les recherches comme celle-ci.

1

Une autre approche à ce problème est de faire une décomposition de mots que vous pouvez utiliser une approche basée sur un dictionnaire: Compound Word Token Filter ou pour utiliser un plugin qui décompose les mots de façon algorithmique: Decompound plugin.

Le mot microsoft serait par ex. être divisé en jetons suivants:

{ 
    "tokens": [ 
     { 
     "token": "microsoft", 
     }, 
     { 
     "token": "micro", 
     }, 
     { 
     "token": "soft", 
     } 
    ] 
} 

Ces jetons vous permettront de rechercher des mots partiels comme vous avez demandé. Comparée à l'approche ngrams mentionnée dans l'autre réponse, cette approche se traduira par une précision plus élevée avec seulement un rappel légèrement inférieur.