मुझे उन दस्तावेज़ों से मिलान करने की ज़रूरत है जिनमें उप-दस्तावेज़ों का एक सरणी फ़ील्ड है जहां उन उप-दस्तावेजों में से कम से कम एक फ़ील्ड गुम है। इस उदाहरण में (वास्तविक चीज़ का अस्पष्ट रूप), मैं एक जेडी की तलाश में हूं जिसमें कम से कम एक रोशनी है जो खो नहीं गया है। समस्या यह है कि lost_date उप-दस्तावेज़ में केवल तभी मौजूद होता है जब उसका मान सेट किया जाता है।

सूचकांक को देखते हुए:

PUT /jedi_index
{
    "mappings": {
        "jedi-type": {
            "properties": {
                "name": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "lightsabers": {
                    "properties": {
                        "color": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "lost_date": {
                            "type": "date"
                        }
                    }
                }
            }
        }
    }
}

उदाहरण दस्तावेज़ के साथ:

PUT /jedi_index/jedi-type/1
{
    "name": "Luke",
    "lightsabers": [
        {
            "color": "blue",
            "lost_date": "2020-12-23T13:46:37.194000"
        },
        {
            "color": "green"
        }
    ]
}

मैं जिस निकटतम खोज के साथ आ सकता हूं वह यह है। समस्या यह है कि यह केवल जेडी से मेल खाएगा जिसमें कोई खोया हुआ रोशनी नहीं है।

POST /jedi_index/_search
{
    "query": {
        "bool": {
            "must_not": [
                {
                    "exists": {
                        "field": "lightsabers.lost_date"
                    }
                }
            ]
        }
    }
}

ध्यान दें मैं इस क्वेरी को बिना बदले मौजूदा स्कीमा के साथ काम करने की कोशिश कर रहा हूं। साथ ही, मैं मोंगोडीबी क्वेरी सिंटैक्स के साथ अधिक कुशल हूं और विश्वास करता हूं कि उस सिस्टम में समकक्ष क्वेरी होगी:

db.jedi.find({
    lightsabers: {
        $elemMatch: {
            lost_date: {$exists: false}
        }
    }
})
1
turnerd18 4 जिंदा 2021, 18:18

1 उत्तर

सबसे बढ़िया उत्तर

मेरा मानना ​​है कि आपने कुछ चीजों को छोड़कर सब कुछ ठीक किया:

  1. वस्तुओं के संग्रह को उनके काम करने के लिए nested प्रकार के रूप में मैप किया जाना चाहिए
  2. उनसे पूछताछ करने के लिए, आपको आश्चर्यजनक रूप से चीजों को nested क्वेरी में लपेटना होगा।

यह सही (सरलीकृत) मानचित्रण है:

PUT /jedi_index
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "lightsabers": {
        "type": "nested",
        "properties": {
          "color": {
            "type": "text"
          },
          "lost_date": {
            "type": "date"
          }
        }
      }
    }
  }
}

आपके द्वारा दिया गया नमूना दस्तावेज़:

PUT /jedi_index/_doc/1
{
  "name": "Luke",
  "lightsabers": [
    {
      "color": "blue",
      "lost_date": "2020-12-23T13:46:37.194000"
    },
    {
      "color": "green"
    }
  ]
}

अब वास्तविक प्रश्न के लिए, मुझे लगता है कि मैं यहां थोड़ा फंस गया हूं:

मैं एक जेडी की तलाश में हूं जिसमें कम से कम एक लाइटबसर हो जो खो न जाए।

हो सकता है कि कम से कम एक lost_date मौजूद होने की जाँच करना और एक ऐसा दस्तावेज़ होना चाहिए जहाँ यह मौजूद न हो? किसी भी मामले में - मैं कहूंगा कि आपके डेटा को फिर से तैयार करना सबसे अच्छा है, नेस्टेड प्रश्न महंगे हैं।

POST /jedi_index/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "lightsabers",
            "query": {
              "bool": {
                "must_not": [
                  {
                    "exists": {
                      "field": "lightsabers.lost_date"
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "nested": {
            "path": "lightsabers",
            "query": {
              "bool": {
                "filter": [
                  {
                    "exists": {
                      "field": "lightsabers.lost_date"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
0
Evaldas Buinauskas 4 जिंदा 2021, 18:42
धन्यवाद @ evaldas-buinauskas। ठीक यही मैं चाहता हूं कि खोज मेल खाए। तो, स्पष्ट होने के लिए, ऐसा कोई तरीका नहीं है जिससे आप lightsabers नेस्टेड प्रकार बनाए बिना इस क्वेरी को निष्पादित कर सकें? अभी, मैं नेस्टेड दस्तावेज़ों में डेटा का मिलान करने में सक्षम प्रतीत होता हूं, लेकिन इस विशिष्ट प्रकार की क्वेरी के लिए नहीं। मेरी क्वेरी करने के लिए, मुझे उस क्षेत्र को नेस्टेड घोषित करने की आवश्यकता होगी?
 – 
turnerd18
4 जिंदा 2021, 19:32
मैंने lightsabers nested टाइप करने के लिए अपने उदाहरण इंडेक्स को इन-प्लेस अपडेट करने का प्रयास किया, और यह त्रुटि के साथ विफल रहा: object mapping [lightsabers] can't be changed from non-nested to nested मुझे नहीं लगता कि यह मेरे लिए एक विकल्प होगा: (
 – 
turnerd18
4 जिंदा 2021, 19:58
हां, प्रत्येक सरणी वस्तु को अलग-अलग क्वेरी करने में सक्षम होने के लिए, आपको नेस्टेड प्रकार का उपयोग करने की आवश्यकता है। दस्तावेज़ से लिया गया: elastic.co/guide/en/elasticsearch/ Reference/current/nested.html साथ ही, आप अपनी मौजूदा अनुक्रमणिका को कैसे अपडेट करते हैं?
 – 
Evaldas Buinauskas
5 जिंदा 2021, 10:22