簡體   English   中英

如何通過任意數量的字段搜索數據?

[英]How to search through data with arbitrary amount of fields?

我有科學活動的網絡表單生成器。 事件主持人使用任意數量的布爾值,整數,枚舉和文本字段創建注冊表單。

創建的表單用於:

  • 注冊新會員參加活動;
  • 通過注冊會員搜索。

什么是第二項任務(搜索事件成員)的最佳搜索工具? ElasticSearch是否適合此任務?

ElasticSearch自動檢測字段內容以正確索引它,即使以前未定義映射。 所以,是的:ElasticSearch非常適合這些情況。

但是,您可能想微調此行為,或者ElasticSearch應用的默認映射可能與您所需的不符:在這種情況下,請查看默認映射,或者甚至進一步控制動態模板功能。

如果讓最終用戶決定存儲事物的密鑰 ,則映射和集群狀態將不斷增長,這是有問題的。

關於Elasticsearch的常見問題,本文討論了這種情況和建議的解決方案。

本質上,您希望擁有可以由用戶定義為值的所有內容。 使用嵌套文檔,您可以擁有一個key字段和不同映射的值字段,以實現幾乎相同的效果。

我寫了一篇關於如何將任意數據索引到Elasticsearch中,然后按特定字段和值搜索它的文章。 所有這一切,都不會破壞索引映射。

帖子在這里: http : //smnh.me/indexing-and-searching-arbitrary-json-data-using-elasticsearch/

簡而言之,您將需要執行以下步驟以獲取所需的內容:

  1. 創建帖子中描述的特殊索引。
  2. 使用flattenData函數展平要索引的數據:
    https://gist.github.com/smnh/30f96028511e1440b7b02ea559858af4
  3. 使用原始數據和展平的數據創建文檔,並將其索引到Elasticsearch中:

     { "data": { ... }, "flatData": [ ... ] } 
  4. 可選:使用Elasticsearch聚合來查找已索引哪些字段和類型。

  5. flatData對象執行查詢以查找所需內容。

基於您的原始問題,讓我們假設第一個事件主持人創建了一個包含以下字段的表單,以注冊科學事件的成員:

  • name 字符串
  • age
  • sex -男性0 ,女性1

除了這些數據之外,相關事件可能還具有某種ID,我們將其稱為eventId 因此最終文檔可能如下所示:

{
    "eventId": "2T73ZT1R463DJNWE36IA8FEN",
    "name": "Bob",
    "age": 22,
    "sex": 0
}

現在,在索引此文檔之前,我們將使用flattenData函數對其進行展平:

flattenData(document);

這將產生以下數組:

[
    {
        "key": "eventId",
        "type": "string",
        "key_type": "eventId.string",
        "value_string": "2T73ZT1R463DJNWE36IA8FEN"
    },
    {
        "key": "name",
        "type": "string",
        "key_type": "name.string",
        "value_string": "Bob"
    },
    {
        "key": "age",
        "type": "long",
        "key_type": "age.long",
        "value_long": 22
    },
    {
        "key": "sex",
        "type": "long",
        "key_type": "sex.long",
        "value_long": 0
    }
]

然后,我們將把這些數據包裝到我之前顯示的文檔中並對其進行索引。

然后,第二個事件主持人創建另一個具有新字段的表單,該字段具有相同名稱和類型的字段,以及具有相同名稱但類型不同的字段:

  • name 字符串
  • city 字符串
  • sex 字符串 -“男性”或“女性”

該事件主持人決定,男性和女性的形式不必為01 ,而是可以在兩個字符串之間進行選擇-“ male”和“ female”。

讓我們嘗試展平此表單提交的數據:

flattenData({
    "eventId": "F1BU9GGK5IX3ZWOLGCE3I5ML",
    "name": "Alice",
    "city": "New York",
    "sex": "female"
});

這將產生以下數據:

[
    {
        "key": "eventId",
        "type": "string",
        "key_type": "eventId.string",
        "value_string": "F1BU9GGK5IX3ZWOLGCE3I5ML"
    },
    {
        "key": "name",
        "type": "string",
        "key_type": "name.string",
        "value_string": "Alice"
    },
    {
        "key": "city",
        "type": "string",
        "key_type": "city.string",
        "value_string": "New York"
    },
    {
        "key": "sex",
        "type": "string",
        "key_type": "sex.string",
        "value_string": "female"
    }
]

然后,在將扁平化數據包裝在文檔中並將其編入Elasticsearch后,我們可以執行復雜的查詢。

例如,要查找為事件注冊的ID為2T73ZT1R463DJNWE36IA8FEN名為“ Bob”的成員,我們可以執行以下查詢:

{
    "query": {
        "bool": {
            "must": [
                {
                    "nested": {
                        "path": "flatData",
                        "query": {
                            "bool": {
                                "must": [
                                    {"term": {"flatData.key": "eventId"}},
                                    {"match": {"flatData.value_string.keyword": "2T73ZT1R463DJNWE36IA8FEN"}}
                                ]
                            }
                        }
                    }
                },
                {
                    "nested": {
                        "path": "flatData",
                        "query": {
                            "bool": {
                                "must": [
                                    {"term": {"flatData.key": "name"}},
                                    {"match": {"flatData.value_string": "bob"}}
                                ]
                            }
                        }
                    }
                }
            ]
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM