2015-04-21 3 views
5

Я использую ElasticSearch через NEST C#. У меня есть большой список информации о людяхElasticSearch Order By String Length

{ 
    firstName: 'Frank', 
    lastName: 'Jones', 
    City: 'New York' 
} 

Я хотел бы иметь возможность фильтровать и сортировать этот список предметов по LastName, а также порядка по длине так, люди, которые имеют только 5 символов в имени будет быть в начале набора результатов, тогда люди с 10 символами.

Так что с какой-то псевдо-код, который я хотел бы сделать что-то вроде list.wildcard("j*").sort(m => lastName.length)

Я новичок в ElasticSearch поэтому любые примеры были бы очень полезны.

ответ

5

Вы можете сортировать с помощью script-based sorting.

В примере игрушек, я создал тривиальный индекс с несколькими документами:

PUT /test_index 

POST /test_index/doc/_bulk 
{"index":{"_id":1}} 
{"name":"Bob"} 
{"index":{"_id":2}} 
{"name":"Jeff"} 
{"index":{"_id":3}} 
{"name":"Darlene"} 
{"index":{"_id":4}} 
{"name":"Jose"} 

Тогда я могу заказать результаты поиска, как это:

POST /test_index/_search 
{ 
    "query": { 
     "match_all": {} 
    }, 
    "sort": { 
     "_script": { 
     "script": "doc['name'].value.length()", 
     "type": "number", 
     "order": "asc" 
     } 
    } 
} 
... 
{ 
    "took": 2, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 4, 
     "max_score": null, 
     "hits": [ 
     { 
      "_index": "test_index", 
      "_type": "doc", 
      "_id": "1", 
      "_score": null, 
      "_source": { 
       "name": "Bob" 
      }, 
      "sort": [ 
       3 
      ] 
     }, 
     { 
      "_index": "test_index", 
      "_type": "doc", 
      "_id": "4", 
      "_score": null, 
      "_source": { 
       "name": "Jose" 
      }, 
      "sort": [ 
       4 
      ] 
     }, 
     { 
      "_index": "test_index", 
      "_type": "doc", 
      "_id": "2", 
      "_score": null, 
      "_source": { 
       "name": "Jeff" 
      }, 
      "sort": [ 
       4 
      ] 
     }, 
     { 
      "_index": "test_index", 
      "_type": "doc", 
      "_id": "3", 
      "_score": null, 
      "_source": { 
       "name": "Darlene" 
      }, 
      "sort": [ 
       7 
      ] 
     } 
     ] 
    } 
} 

Для фильтрации по длине, я могу использовать script filter подобным образом:

POST /test_index/_search 
{ 
    "query": { 
     "filtered": { 
     "query": { 
      "match_all": {} 
     }, 
     "filter": { 
      "script": { 
       "script": "doc['name'].value.length() > 3", 
       "params": {} 
      } 
     } 
     } 
    }, 
    "sort": { 
     "_script": { 
     "script": "doc['name'].value.length()", 
     "type": "number", 
     "order": "asc" 
     } 
    } 
} 
... 
{ 
    "took": 3, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 3, 
     "max_score": null, 
     "hits": [ 
     { 
      "_index": "test_index", 
      "_type": "doc", 
      "_id": "4", 
      "_score": null, 
      "_source": { 
       "name": "Jose" 
      }, 
      "sort": [ 
       4 
      ] 
     }, 
     { 
      "_index": "test_index", 
      "_type": "doc", 
      "_id": "2", 
      "_score": null, 
      "_source": { 
       "name": "Jeff" 
      }, 
      "sort": [ 
       4 
      ] 
     }, 
     { 
      "_index": "test_index", 
      "_type": "doc", 
      "_id": "3", 
      "_score": null, 
      "_source": { 
       "name": "Darlene" 
      }, 
      "sort": [ 
       7 
      ] 
     } 
     ] 
    } 
} 

Вот код, который я использовал:

http://sense.qbox.io/gist/22fef6dc5453eaaae3be5fb7609663cc77c43dab

P.S .: Если какой-либо из последних имен будет содержать пробелы, вы можете захотеть использовать "index": "not_analyzed" на этом поле.

+2

Предположим, он часто выполняет этот поиск на большом количестве документов, стоит ли просто индексировать длину? – Robin

+0

Да, конечно, если это вариант. Хорошая точка зрения. –

+0

Спасибо за такую ​​отличную обратную связь. @Robin: по большей части мои данные не изменятся, поэтому индексирование длины, которое, как мне кажется, будет выгодным. Если у вас есть какие-либо ссылки, вы можете указать мне, что это было бы здорово. – mvcNewbie