Il y a deux ou trois choses que je peux voir qui peut aider ici:
- Par défaut, les cas de chameau NEST noms de propriété POCO lors de la sérialisation les dans le cadre de la requête JSON dans la demande, alors
x => x.Question
va sérialiser à "question"
. En regardant votre mapping cependant, les noms de champs dans Elasticsearch sont en Pascal, donc ce que le client fait ne correspondra pas à ce qui est dans Elasticsearch.
Vous pouvez modifier NEST sérialise les noms de propriétés POCO en utilisant .DefaultFieldNameInferrer(Func<string, string>)
sur ConnectionSettings
const string ESServer = "http://localhost:9200";
ConnectionSettings settings = new ConnectionSettings(new Uri(ESServer))
.DefaultIndex("tiky");
.MapDefaultTypeNames(map => map.Add(typeof(DAL.Faq), "faq"))
// pass POCO property names through verbatim
.DefaultFieldNameInferrer(s => s);
ElasticClient client = new ElasticClient(settings);
Comme mentionné Rob dans les commentaires, a term queryn'Analysons pas l'entrée de requête. Lors de l'exécution d'une requête à terme sur un champ analysé à l'heure de l'index, afin d'obtenir des correspondances, le texte de la requête que vous passez à la requête à terme doit prendre en compte l'analyse appliquée au moment de l'index. Par exemple,
Question
est analysé avec the Standard Analyzer
- Une valeur
Question
de "What's the Question?"
sera analysé et indexé sous forme de jetons "what's"
, "the"
et "question"
- Une requête à long terme aurait besoin d'avoir une entrée de requête de
"what's"
, "the"
ou "question"
être un match
Une requête de correspondance, contrairement à une requête de terme, analyse l'entrée de requête, de sorte que la sortie de l'analyse de recherche sera utilisée pour trouver des correspondances. En conjonction avec le cas Pascal mis en évidence en 1., vous devriez maintenant obtenir les documents retournés.Vous pouvez également avoir le meilleur des deux mondes dans Elasticsearch, c'est-à-dire analyser les entrées au moment de l'indexation pour la fonctionnalité de recherche de texte intégral ainsi que l'entrée d'index sans analyse pour obtenir des correspondances exactes. Cela se fait avec multi-fields et voici un exemple de création d'une cartographie qui indexe Question
propriétés à la fois comme analysées et non analysées
public class Faq
{
public string Question { get; set; }
}
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "default-index";
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex)
.DefaultFieldNameInferrer(s => s);
var client = new ElasticClient(connectionSettings);
if (client.IndexExists(defaultIndex).Exists)
client.DeleteIndex(defaultIndex);
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<Faq>(mm => mm
// let NEST infer mapping from the POCO
.AutoMap()
// override any inferred mappings explicitly
.Properties(p => p
.String(s => s
.Name(n => n.Question)
.Fields(f => f
.String(ss => ss
.Name("raw")
.NotAnalyzed()
)
)
)
)
)
)
);
La mise en correspondance pour cela ressemble
{
"mappings": {
"faq": {
"properties": {
"Question": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
Le champ sous "raw"
sous la "Question"
le champ indexera la valeur de la propriété Question
sans aucune analyse, c'est-à-dire verbatim. Ce champ sous-marin peut maintenant être utilisé dans une requête à long terme pour trouver des correspondances exactes
client.Search<Faq>(s => s
.Query(q => q
.Term(f => f.Question.Suffix("raw"), "What's the Question?")
)
);
qui trouvent les résultats obtenus pour l'exemple précédent.
Pouvez-vous partager le mappage d'index? 'http: // localhost: 9200/tiky/_mapping' – Rob
@Rob Bien sûr, j'ai mis à jour la question –
Le champ' Question' est analysé et 'terms query' fonctionne avec les champs' not_analyzed'. Vous pouvez en lire plus à ce sujet [ici] (https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html). – Rob