существуют ли какие-либо операции Elasticsearch, близкие к проекции MongDB?

#elasticsearch #elasticsearch-aggregation #elasticsearch-6

#elasticsearch #elasticsearch-агрегация #elasticsearch-6

Вопрос:

я импортировал свой mongodb в elasticsearch для выполнения некоторой сложной сортировки, часть которой выглядит так

 {
    "ProductName": {
        "WORLDWIDE": {
            "zh": "产品 1",
            "en": "product 1"
        },
        "CHINA": {
            "zh": null,
            "en": null
        }
    }
}
  

в агрегации Mongodb я могу использовать

 $project: {
    "ProductName": {
        $ifNull: [ {$ifNull: [ "$ProductName.CHINA.zh", "$ProductName.CHINA.en" ]}, {$ifNull: [ "$ProductName.WORLDWIDE.zh", "$ProductName.WORLDWIDE.en" ]} ]
    }
}
  

чтобы получить конкретное значение в одно поле без вложенности.

возможно ли сделать то же самое в elasticsearch?

Ответ №1:

Я придумал следующие поля сценария, в которых я создал новую переменную my_productName и присвоил значения в соответствии с условием, которое вы упомянули в запросе агрегации mongo.

Обратите внимание, что я предполагаю, что поля имеют тип keyword , иначе это невозможно с использованием текстового типа данных. Не стесняйтесь изменять условие в приведенном ниже запросе как самоочевидное.

Также я предполагаю, что все ваши документы будут иметь любое из значений, указанных в том же документе в вашем вопросе.

Запрос запроса:

 POST <your_index_name>/_search
{
    "query" : {
        "match_all": {}
    },
    "script_fields" : {
        "my_productName" : {
            "script" : {
                "lang": "painless",
                "source": """
                if(doc['ProductName.CHINA.zh'].value!=null){
                  return doc['ProductName.CHINA.zh'].value;
                }else if(doc['ProductName.CHINA.en'].value!=null){
                  return doc['ProductName.CHINA.en'].value;
                }else if(doc['ProductName.WORLDWIDE.zh'].value!=null){
                  return doc['ProductName.WORLDWIDE.zh'].value;
                }else {
                  return doc['ProductName.WORLDWIDE.ch'].value;
                }

                """
            }
        }
    }
}
  

Ответ на запрос:

 {
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "<your_index_name>",
        "_type" : "<your_type_name>",
        "_id" : "1",
        "_score" : 1.0,
        "fields" : {
          "my_productName" : [
            "产品 1"
          ]
        }
      }
    ]
  }
}
  

Еще одна вещь, если вы хотите, чтобы появлялись другие поля, которые вы можете добавить
"_source": {"fieldname1", "fieldname2} поверх "query" .

Надеюсь, это поможет, и если это поможет, не стесняйтесь голосовать и / или принять ответ 🙂

Дайте мне знать, если у вас есть какие-либо вопросы.

Комментарии:

1. Конечно, держите меня в курсе. Рад помочь!!