Czy wyszukiwanie elastyczne zwraca tylko niektóre pola?

434

Używam elasticsearch do indeksowania moich dokumentów.

Czy można poinstruować, aby zwracał tylko określone pola zamiast całego zapisanego dokumentu json?

użytkownik1199438
źródło
1
elastic.co/guide/en/elasticsearch/reference/current/… , pamiętaj, że możesz również wykluczyć tylko niektóre pola
Christophe Roussy

Odpowiedzi:

619

Tak! Użyj filtra źródłowego . Jeśli szukasz w JSON, będzie wyglądać mniej więcej tak:

{
    "_source": ["user", "message", ...],
    "query": ...,
    "size": ...
}

W ES 2.4 i wcześniejszych można również użyć opcji pól w interfejsie API wyszukiwania :

{
    "fields": ["user", "message", ...],
    "query": ...,
    "size": ...
}

Jest to przestarzałe w ES 5+. A filtry źródłowe i tak są potężniejsze!

kevingessner
źródło
12
pamiętaj, aby zdefiniować je jako „przechowywane”: prawda w mapowaniu. W przeciwnym razie ES nadal ładuje dokument _source i ładuje stamtąd pola. Może mieć wpływ na wydajność, jeśli zwracane dane są stosunkowo małe do rozmiaru całego dokumentu.
Zaar Hai,
6
miałeś na myśli „store”: true
sscarduzio
czy są one wykonane w pliku conf lub gdzie dokładnie?
vbNewbie
@vbNewbie: Gdziekolwiek definiujesz mapowanie. Jeśli nie definiujesz mapowania jawnie i nie opierasz się na ES, aby go wygenerować, musisz zdefiniować mapowanie dla pól, które ES ma przechowywać. Możesz zdefiniować mapowanie tylko dla pól, w których chcesz zachować specjalne zachowanie (np. „Store”: true, „index”: „not_analyzed”) lub wszystkich pól. Aby uzyskać więcej informacji, zapoznaj się z dokumentami mapowania.
Sangharsh
3
pola nie są już obsługiwane w nowszych wersjach. zamiast tego używaj pól przechowywanych :)
Sachin Sharma
88

Uważam, że dokumenty get apisą pomocne - szczególnie dwie sekcje, Filtrowanie źródeł i Pola : https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source- filtracja

Mówią o filtrowaniu źródeł:

Jeśli potrzebujesz tylko jednego lub dwóch pól z pełnego _source, możesz użyć parametrów _source_include & _source_exclude, aby uwzględnić lub odfiltrować potrzebne części. Może to być szczególnie pomocne w przypadku dużych dokumentów, w których częściowe pobieranie może zaoszczędzić na narzutach sieciowych

Które idealnie pasowały do ​​mojego przypadku użycia. Skończyło się na tym, że tak po prostu przefiltrowałem źródło (używając skrótu):

{
    "_source": ["field_x", ..., "field_y"],
    "query": {      
        ...
    }
}

Do Twojej wiadomości w dokumentach podają parametr parametr pola :

Operacja get umożliwia określenie zestawu przechowywanych pól, które zostaną zwrócone poprzez przekazanie parametru pola.

Wydaje się, że obsługuje pola, które zostały specjalnie zapisane, gdzie umieszcza każde pole w tablicy. Jeśli określone pola nie zostaną zapisane, pobierze każde z _source, co może spowodować „wolniejsze” pobieranie. Miałem również problemy z uzyskaniem go, aby zwracał pola typu obiektu.

Podsumowując, masz dwie opcje: filtrowanie źródła lub pola [przechowywane].

Markus Coetzee
źródło
Wykonał dla mnie lewę. Miałem problem ze zwróceniem geo_point za pomocą „pól”, ale „_source” działa dobrze, dzięki!
Yonnaled,
23
For the ES versions 5.X and above you can a ES query something like this

    GET /.../...
    {
      "_source": {
        "includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
      },
      .
      .
      .
      .
    }
Pinkesh Sharma
źródło
12

W Elasticsearch 5.x powyższe podejście jest przestarzałe. Możesz użyć metody _source, ale w niektórych sytuacjach sensowne jest przechowywanie pola. Na przykład, jeśli masz dokument z tytułem, datą i bardzo dużym polem zawartości, możesz pobrać tylko tytuł i datę bez konieczności wyodrębniania tych pól z dużego pola _source:

W takim przypadku użyłbyś:

{  
   "size": $INT_NUM_OF_DOCS_TO_RETURN,
   "stored_fields":[  
      "doc.headline",
      "doc.text",
      "doc.timestamp_utc"
   ],
   "query":{  
      "bool":{  
         "must":{  
            "term":{  
               "doc.topic":"news_on_things"
            }
         },
         "filter":{  
            "range":{  
               "doc.timestamp_utc":{  
                  "gte":1451606400000,
                  "lt":1483228800000,
                  "format":"epoch_millis"
               }
            }
         }
      }
   },
   "aggs":{  

   }
}

Zobacz dokumentację dotyczącą sposobu indeksowania przechowywanych pól. Zawsze chętny na upvote!

woltob
źródło
7
here you can specify whichever field you want in your output and also which you don't.

  POST index_name/_search
    {
        "_source": {
            "includes": [ "field_name", "field_name" ],
            "excludes": [ "field_name" ]
        },
        "query" : {
            "match" : { "field_name" : "value" }
        }
    }
Gauraw
źródło
7

filtrowanie odpowiedzi

Wszystkie interfejsy API REST akceptują parametr ścieżka_filtru, którego można użyć do zmniejszenia odpowiedzi zwracanej przez wyszukiwanie elastyczne. Ten parametr przyjmuje listę filtrów oddzielonych przecinkami wyrażonych notacją kropkową.

https://stackoverflow.com/a/35647027/844700

The Demz
źródło
5

Żądanie GET API REST można wykonać za pomocą parametru „_source”.

Przykładowe zapytanie

http://localhost:9200/opt_pr/_search?q=SYMBOL:ITC AND OPTION_TYPE=CE AND TRADE_DATE=2017-02-10 AND EXPIRY_DATE=2017-02-23&_source=STRIKE_PRICE

Odpowiedź

{
"took": 59,
"timed_out": false,
"_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
},
"hits": {
    "total": 104,
    "max_score": 7.3908954,
    "hits": [
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uLc",
            "_score": 7.3908954,
            "_source": {
                "STRIKE_PRICE": 160
            }
        },
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uLh",
            "_score": 7.3908954,
            "_source": {
                "STRIKE_PRICE": 185
            }
        },
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uLi",
            "_score": 7.3908954,
            "_source": {
                "STRIKE_PRICE": 190
            }
        },
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uLm",
            "_score": 7.3908954,
            "_source": {
                "STRIKE_PRICE": 210
            }
        },
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uLp",
            "_score": 7.3908954,
            "_source": {
                "STRIKE_PRICE": 225
            }
        },
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uLr",
            "_score": 7.3908954,
            "_source": {
                "STRIKE_PRICE": 235
            }
        },
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uLw",
            "_score": 7.3908954,
            "_source": {
                "STRIKE_PRICE": 260
            }
        },
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uL5",
            "_score": 7.3908954,
            "_source": {
                "STRIKE_PRICE": 305
            }
        },
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uLd",
            "_score": 7.381078,
            "_source": {
                "STRIKE_PRICE": 165
            }
        },
        {
            "_index": "opt_pr",
            "_type": "opt_pr_r",
            "_id": "AV3K4QTgNHl15Mv30uLy",
            "_score": 7.381078,
            "_source": {
                "STRIKE_PRICE": 270
            }
        }
    ]
}

}

Ironluca
źródło
Jest to dla mnie bardzo użyteczne.
Thusitha Indunil
4

Tak, korzystając z filtru źródłowego, możesz to zrobić, oto filtrowanie źródłowe dokumentów

Przykładowe zapytanie

POST index_name/_search
 {
   "_source":["field1","filed2".....] 
 }

Wyjście będzie

{
  "took": 57,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "index_name",
        "_type": "index1",
        "_id": "1",
        "_score": 1,
        "_source": {
          "field1": "a",
          "field2": "b"
        },
        {
          "field1": "c",
          "field2": "d"
        },....
      }
    ]
  }
}
RCP
źródło
2

W Javie możesz użyć setFetchSource w następujący sposób:

client.prepareSearch(index).setTypes(type)
            .setFetchSource(new String[] { "field1", "field2" }, null)
użytkownik1693371
źródło
2

Na przykład masz dokument z trzema polami:

PUT movie/_doc/1
{
  "name":"The Lion King",
  "language":"English",
  "score":"9.3"
}

Jeśli chcesz wrócić namei scoremożesz użyć następującego polecenia:

GET movie/_doc/1?_source_includes=name,score

Jeśli chcesz uzyskać pola pasujące do wzorca:

GET movie/_doc/1?_source_includes=*re

Może wykluczyć niektóre pola:

GET movie/_doc/1?_source_excludes=score
Yao Pan
źródło
0

Korzystając z Java API, używam następujących elementów, aby uzyskać wszystkie rekordy z zestawu określonych pól:

public List<Map<String, Object>> getAllDocs(String indexName) throws IOException{
    int scrollSize = 1000;
    List<Map<String,Object>> data = new ArrayList<>();
    SearchResponse response = null;
    while( response == null || response.getHits().getHits().length != 0){
        response = client.prepareSearch(indexName)
            .setTypes("typeName")  // The document types to execute the search against. Defaults to be executed against all types.
        .setQuery(QueryBuilders.matchAllQuery())
        .setFetchSource(new String[]{"field1", "field2"}, null)
        .setSize(scrollSize)
        .execute()
        .actionGet();
        for(SearchHit hit : response.getHits()){
            System.out.println(hit.getSourceAsString());
        }
    }
    return data;
}
Doi
źródło