2016-04-21 72 views
0

使用下面顯示的示例json,試圖檢索包含至少一個類別的所有文檔,該類別是數組對象包裝,類別具有文本值'drinks'以下查詢但返回的結果爲空。有人可以幫我解決這個問題嗎?包含數組的屬性的文檔Db查詢過濾器

SELECT items.id 
,items.description 
,items.Categories 
FROM items 
WHERE ARRAY_CONTAINS(items.Categories.Category.Text, "drink") 

{ 
 
    "id": "1dbaf1d0-6549-11a0-88a8-001256957023", 
 
    "Categories": { 
 
    "Category": [{ 
 
     "Type": "GS1", 
 
     "Id": "10000266", 
 
     "Text": "Stimulants/Energy Drinks Ready to Drink" 
 
    }, { 
 
     "Type": "GS2", 
 
     "Id": "10000266", 
 
     "Text": "Healthy Drink" 
 
    }] 
 
    } 
 
},
注:JSON是有點奇怪具有由對象本身纏繞陣列 - 這JSON是從XML因此結果的轉換。因此,請假設我無法控制此對象如何保存爲json

回答

2

如果是我並且我正在使用此要求構建生產系統,那麼我會使用Azure搜索。 Here是一些關於將它連接到DocumentDB的信息。

如果你不想這樣做,我們必須忍受你不能改變文檔形狀的限制,我唯一能做的就是使用用戶定義函數(UDF) )是這樣的:

function GetItemsWithMatchingCategories(categories, matchingString) { 
 
    if (Array.isArray(categories) && categories !== null) { 
 
    var lowerMatchingString = matchingString.toLowerCase(); 
 
    for (var index = 0; index < categories.length; index++) { 
 
     var category = categories[index]; 
 
     var categoryName = category.Text.toLowerCase(); 
 
     if (categoryName.indexOf(lowerMatchingString) >= 0) { 
 
     return true; 
 
     } 
 
    } 
 
    } 
 
}

注意,上面的代碼是由提問者其實是想出來,所以它的有些測試後修改。

你會用這樣的查詢使用它:

SELECT * FROM items WHERE udf.GetItemsWithMatchingCategories(items.Categories, "drink") 

此外,請注意,這將導致全表掃描(除非你可以與可以使用索引其他標準結合起來),這可能或者可能不符合你的表現/ RU限制。

+0

謝謝:)。 UDF的確是正確和快速的解決方案。然而還有一個問題(我可以把它移到差異文件中) - 但是,以防萬一你知道 - 我該如何測試(單元和集成)腳本。在茉莉花有一點經驗,但想知道如果天藍色的SDK腳本有任何。再次感謝!我將其標記爲答案。將其修改一下以匹配我的屬性。 – Jaya

+1

UDF很容易通過NodeJS上的標準JavaScript測試工具進行測試,因爲它們只是JavaScript函數。我使用NodeUnit,但Jasmine是常用選擇。爲了在NodeJS上測試存儲過程(sprocs),我創建了documentdb-mock。 –

+0

感謝您在完成工作後編輯代碼。我發佈未經測試的代碼感覺不好,但沒有時間自己嘗試一下。希望從我手寫的例子中找出它並不難。 :-) –

3

您需要在查詢中展開文檔以通過將數組連接回主文檔來獲得所需的結果。你想看起來像這樣的查詢:

SELECT items.id, items.Categories 
FROM items 
JOIN Category IN items.Categories.Category 
WHERE CONTAINS(LOWER(Category.Text), "drink") 

然而,因爲沒有一個DISTINCT查詢的概念,這會產生重複,等於包含單詞「喝」類項目的數量。所以這個查詢將產生兩倍的範例文件是這樣的:

[ 
    { 
    "id": "1dbaf1d0-6549-11a0-88a8-001256957023", 
    "Categories": { 
     "Category": [ 
     { 
      "Type": "GS1", 
      "Id": "10000266", 
      "Text": "Stimulants/Energy Drinks Ready to Drink" 
     }, 
     { 
      "Type": "GS2", 
      "Id": "10000266", 
      "Text": "Healthy Drink" 
     } 
     ] 
    } 
    }, 
    { 
    "id": "1dbaf1d0-6549-11a0-88a8-001256957023", 
    "Categories": { 
     "Category": [ 
     { 
      "Type": "GS1", 
      "Id": "10000266", 
      "Text": "Stimulants/Energy Drinks Ready to Drink" 
     }, 
     { 
      "Type": "GS2", 
      "Id": "10000266", 
      "Text": "Healthy Drink" 
     } 
     ] 
    } 
    } 
] 

如果分類數組中包含了很多已經在他們「喝」範疇的項目這可能是有問題的,價格昂貴。

您可以剪切下來,如果你是通過更改查詢只在一個類別感興趣:

SELECT items.id, Category 
FROM items 
JOIN Category IN items.Categories.Category 
WHERE CONTAINS(LOWER(Category.Text), "drink") 

這將產生更精確的結果,只有每個匹配分類項目顯示重複的ID字段過一次:

[{ 
    "id": "1dbaf1d0-6549-11a0-88a8-001256957023", 
    "Category": { 
     "Type": "GS1", 
     "Id": "10000266", 
     "Text": "Stimulants/Energy Drinks Ready to Drink" 
    } 
    }, 
    { 
    "id": "1dbaf1d0-6549-11a0-88a8-001256957023", 
    "Category": { 
     "Type": "GS2", 
     "Id": "10000266", 
     "Text": "Healthy Drink" 
    } 
    }] 

否則,你將有當您從查詢讓他們回來,除去重複的文件過濾結果。

+0

除非我弄錯了,否則LOWER的使用會導致它會始終導致全表掃描,是否正確?看看這個或UDF方法是否需要更多的RU會很有趣。公平起見,你還必須考慮重複數據刪除和比較。 –

+1

謝謝!該查詢確實奏效,但如前所述,它造成了重複,並且相當於額外的重複工作,而且某些項目包含大約5-6個類別,並且乘以檢索的項目數量是不可行的,但是再次感謝您給我一個工作查詢:)它確實幫助我編寫更好的查詢並更好地理解它們! - Upvoted! – Jaya

相關問題