2016-12-08 4 views
1

Elasticsearch Version: 5.0.2Elasticsearch einfachen Begriff Abfrage gibt seltsame Partituren

ich bevölkern meine Index mit:

{_id: 1, tags: ['plop', 'plip', 'plup']}, 
{_id: 2, tags: ['plop', 'plup']}, 
{_id: 3, tags: ['plop']}, 
{_id: 4, tags: ['plap', 'plep']}, 
{_id: 5, tags: ['plop', 'plip', 'plup']}, 
{_id: 6, tags: ['plup', 'plip']}, 
{_id: 7, tags: ['plop', 'plip']} 

Dann würde Ich mag die max relevanten Zeilen für Tags plop und plip abzurufen:

query: { 
    bool: { 
    should: [ 
     {term: {tags: {value:'plop', _name: 'plop'}}}, 
     {term: {tags: {value:'plip', _name: 'plip'}}} 
    ] 
    } 
} 

, die äquivalent ist (aber ich verwendet, um die ersteren zu debug):

query: { 
    bool: { 
    should: [ 
     {terms: {tags: ['plop', 'plip']}} 
    ] 
    } 
} 

Dann finde ich wirklich seltsam Partituren:

[ 
    { id: '2', score: 0.88002616, tags: [ 'plop', 'plup' ] }, 
    { id: '6', score: 0.88002616, tags: [ 'plup', 'plip' ] }, 
    { id: '5', score: 0.5063205, tags: [ 'plop', 'plip', 'plup' ] }, 
    { id: '7', score: 0.3610978, tags: [ 'plop', 'plip' ] }, 
    { id: '1', score: 0.29277915, tags: [ 'plop', 'plip', 'plup' ] }, 
    { id: '3', score: 0.2876821, tags: [ 'plop' ] } 
] 

Hier die Einzelheiten der Antwort ist:

{ 
    "took": 1, 
    "timed_out": false, 
    "_shards": { 
    "total": 5, 
    "successful": 5, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 6, 
    "max_score": 0.88002616, 
    "hits": [ 
     { 
     "_index": "myindex", 
     "_type": "mytype", 
     "_id": "2", 
     "_score": 0.88002616, 
     "_source": { 
      "tags": [ 
      "plop", 
      "plup" 
      ] 
     }, 
     "matched_queries": [ 
      "plop" 
     ] 
     }, 
     { 
     "_index": "myindex", 
     "_type": "mytype", 
     "_id": "6", 
     "_score": 0.88002616, 
     "_source": { 
      "tags": [ 
      "plup", 
      "plip" 
      ] 
     }, 
     "matched_queries": [ 
      "plip" 
     ] 
     }, 
     { 
     "_index": "myindex", 
     "_type": "mytype", 
     "_id": "5", 
     "_score": 0.5063205, 
     "_source": { 
      "tags": [ 
      "plop", 
      "plip", 
      "plup" 
      ] 
     }, 
     "matched_queries": [ 
      "plop", 
      "plip" 
     ] 
     }, 
     { 
     "_index": "myindex", 
     "_type": "mytype", 
     "_id": "7", 
     "_score": 0.3610978, 
     "_source": { 
      "tags": [ 
      "plop", 
      "plip" 
      ] 
     }, 
     "matched_queries": [ 
      "plop", 
      "plip" 
     ] 
     }, 
     { 
     "_index": "myindex", 
     "_type": "mytype", 
     "_id": "1", 
     "_score": 0.29277915, 
     "_source": { 
      "tags": [ 
      "plop", 
      "plip", 
      "plup" 
      ] 
     }, 
     "matched_queries": [ 
      "plop", 
      "plip" 
     ] 
     }, 
     { 
     "_index": "myindex", 
     "_type": "mytype", 
     "_id": "3", 
     "_score": 0.2876821, 
     "_source": { 
      "tags": [ 
      "plop" 
      ] 
     }, 
     "matched_queries": [ 
      "plop" 
     ] 
     } 
    ] 
    } 
} 

also zwei Fragen:

  1. Warum eine Reihe maching nur eine Abfrage (id 2 und 6) haben eine bessere Punktzahl als eine übereinstimmende zwei (id 1, 5 und 7)?
  2. Warum können zwei Zeilen mit denselben Tags unterschiedliche Werte haben? (ID 1 und 5)

Habe ich etwas übersehen?

+0

Tags ist nicht_analysiert? – blackmamba

+0

Karte Tags als nicht_analysiert und es wird gut funktionieren – blackmamba

+0

Es funktioniert nicht. Werfen Sie einen Blick auf meinen Kommentar zur ersten Antwort für weitere Informationen. – Gnucki

Antwort

1

Das Problem, das ich schön in der Antwort von JGR erklärt hatte, ist. Die Lösung, die ich gefunden habe, ist dfs_query_then_fetch als search type zu verwenden.

Hier ist die resultierende Abfrage mit dem JavaScript-Client:

body: { 
    query: { 
    bool: { 
     should: [ 
     {terms: {tags: ['plop', 'plip']}} 
     ] 
    } 
    }, 
    searchType: 'dfs_query_then_fetch' 
} 

Beachten Sie, dass mit mehr Daten in dem Indextyp, wäre dies sicherlich nicht, weil Partituren natürlich zwischen Scherben ausgleichen würden benötigt werden.

1

Ok ich finde dein wirkliches Problem. Elastitcsearch verwendet standardmäßig 5 Shards, um Ihre Indexdaten zu speichern, und wenn Sie eine kleine Zahl haben, kann es für den Fall, dass Sie Ihren _score-Wert berechnen, eine Rolle spielen. Eine Theorie über Scherben: https://www.elastic.co/guide/en/elasticsearch/reference/current/_basic_concepts.html

Warum ist es wichtig? Denn für eine bessere Leistung macht jeder Shard _Score-Computing auf seinen eigenen Daten. Aber während der Berechnung Elasticsearch Score-Wert IDF/TF-Algorithmus verwenden, die auf Gesamtzahl der Dokumente und Frequenz verlässt sich hinsichtlich des Suchens (IN SHARD) (https://www.elastic.co/guide/en/elasticsearch/guide/current/scoring-theory.html)

Um dieses Problem zu lösen, können Sie Index mit einer Scherbe wie folgt erstellen:

{ 
"settings": { 
     "number_of_shards" : 1, 
     "number_of_replicas" : 0 
    }, 
    "mappings": { 
    "my_type": { 
     "properties": { 
     "tags": { 
      "type": "keyword" 
     } 
     } 
    } 
    } 
} 

Sie können mit meiner Theorie überprüfen in Ihrer Suchanfrage erklären:

http://localhost:9200/test1/my_type/_search?explain

Oder Sie können dieses Beispiel lesen, wenn Sie mehr brauchen;) Das sind meine Ergebnisse für Ihre Abfrage: [ „Plopp“, „plip“]

{ 
    "took": 5, 
    "timed_out": false, 
    "_shards": { 
    "total": 5, 
    "successful": 5, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 6, 
    "max_score": 0.9808292, 
    "hits": [ 
     { 
     "_index": "test", 
     "_type": "my_type", 
     "_id": "2", 
     "_score": 0.9808292, 
     "_source": { 
      "tags": [ 
      "plop", 
      "plup" 
      ] 
     } 
     }, 
     { 
     "_index": "test", 
     "_type": "my_type", 
     "_id": "6", 
     "_score": 0.9808292, 
     "_source": { 
      "tags": [ 
      "plup", 
      "plip" 
      ] 
     } 
     }, 
     { 
     "_index": "test", 
     "_type": "my_type", 
     "_id": "5", 
     "_score": 0.5753642, 
     "_source": { 
      "tags": [ 
      "plop", 
      "plip", 
      "plup" 
      ] 
     } 
     }, 
     { 
     "_index": "test", 
     "_type": "my_type", 
     "_id": "1", 
     "_score": 0.36464313, 
     "_source": { 
      "tags": [ 
      "plop", 
      "plip", 
      "plup" 
      ] 
     } 
     }, 
     { 
     "_index": "test", 
     "_type": "my_type", 
     "_id": "7", 
     "_score": 0.36464313, 
     "_source": { 
      "tags": [ 
      "plop", 
      "plip" 
      ] 
     } 
     }, 
     { 
     "_index": "test", 
     "_type": "my_type", 
     "_id": "3", 
     "_score": 0.2876821, 
     "_source": { 
      "tags": [ 
      "plop" 
      ] 
     } 
     } 
    ] 
    } 
} 

Warum Dokument mit Plopp ist, plip, PLUP als dritte ? Prüfen Sie erklären für diese:

"_shard": "[test][1]", 
     "_node": "LjGrgIa7QgiPlEvMxqKOdA", 
     "_index": "test", 
     "_type": "my_type", 
     "_id": "5", 
     "_score": 0.5753642, 
     "_source": { 
      "tags": [ 
      "plop", 
      "plip", 
      "plup" 
      ] 
     }, 

Dies ist der einzige doc in diesem Scherbe: Test [1] (i in anderen zurück docs prüft) !! Daher ist der IDF-Wert gleich "1", was der höchstmögliche Wert ist. Score = TF/IDF (für niedrigere IDF ist der Score höher). Überprüfen Sie, wie diese 0 ist.5753642 Punktzahl für diese doc berechnet:

"value": 0.2876821, 
        "description": "weight(tags:plop... 

         "details": [ 
         { 
          "value": 0.2876821, 
          "description": "idf(docFreq=1, docCount=1)", 

Summe mit

{ 
        "value": 0.2876821, 
        "description": "weight(tags:plip.. 

          "value": 0.2876821, 
          "description": "idf(docFreq=1, docCount=1)", 
          "details": [] 
         }, 
+0

Es funktioniert nicht. Ich denke, dass die meisten Analysatoren "plop" und "plip" als "plop" und "plip" analysieren, also bin ich nicht so überrascht. Außerdem glaube ich nicht, dass ein falscher Analysator das Problem erklären würde. 2. Danke für deine Antwort. – Gnucki

+0

@Gnucki Ja, du hast Recht! Jetzt habe ich genau die gleichen Dokumente wie deine eingefügt und auch diese seltsamen Ergebnisse bekommen. Ich erklärte dies und gab Ihnen eine Lösung, um dies zu beheben. – jgr

+0

Vielen Dank für Ihre Untersuchung! Genau das passiert, du hast Recht. Es ist jedoch schwierig, nur ein Shard zu setzen, um das Problem zu lösen. Ich habe stattdessen [searchType] (https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-search-type.html#dfs-query-then-fetch) verwendet – Gnucki

Verwandte Themen