2016-01-14 38 views
2
{ 
"batters": 
    { 
    "batter":[ 
      { "id": "1001", "type": "Regular" }, 
      { "id": "1002", "type": "Chocolate" }, 
      { "id": "1003", "type": "Blueberry" }, 
      { "id": "1004", "type": "Devil's Food" } 
    ] 
    }, 
    "topping":[ 
      { "id": "5001", "type": "None" }, 
      { "id": "5002", "type": "Glazed" }, 
      { "id": "5005", "type": "Sugar" }, 
      { "id": "5007", "type": "Powdered Sugar" }, 
      { "id": "5006", "type": "Chocolate with Sprinkles" }, 
      { "id": "5003", "type": "Chocolate" }, 
      { "id": "5004", "type": "Maple" } 
    ] 
} 

基本上在這裏有全文搜索,我需要對「batters.batter」和「batters.topping」進行索引,即對兩個屬性進行索引。如何處理這種全文搜索。請解釋一下這個方法,我會通過REST API實現我的搜索。提前感謝您。如何做全文索引和搜索下面的json在ArangoDb中的文檔?

+0

做了回答滿足您的需求?如果是的話,你能把它標記爲已接受嗎?如果沒有,缺少什麼? – dothebart

回答

5

解決此問題的最佳方法是稍微更改數據佈局,因爲全文索引只能處理一個屬性,並且索引兩次索引不會很快。因此我們使用匿名圖來將字符串連接到它們的對象。

所以,我們創建了兩個(頂點)集合,一個邊集合,一個頂點集合與fultext指數:

而且文檔保存到他們的關係綁在一起。 我們使用_key屬性,它被用於引用頂點在_from_to緣關係:

db.dishStrings.save({"_key": "1001", "name": "Regular" , type: "Batter"}); 
db.dishStrings.save({"_key": "1002", "name": "Chocolate", type: "Batter" }); 
db.dishStrings.save({"_key": "1003", "name": "Blueberry", type: "Batter"}); 
db.dishStrings.save({"_key": "1004", "name": "Devil's Food", type: "Batter"}); 
db.dishStrings.save({"_key": "5001", "name": "None", type: "Topping"}); 
db.dishStrings.save({"_key": "5002", "name": "Glazed", type: "Topping"}); 
db.dishStrings.save({"_key": "5005", "name": "Sugar", type: "Topping"}); 
db.dishStrings.save({"_key": "5007", "name": "Powdered Sugar", type: "Topping"}); 
db.dishStrings.save({"_key": "5006", "name": "Chocolate with Sprinkles", type: "Topping"}); 
db.dishStrings.save({"_key": "5003", "name": "Chocolate", type: "Topping"}); 
db.dishStrings.save({"_key": "5004", "name": "Maple", type: "Topping"}); 

db.dishEdges.save("dishStrings/1001", "dish/batter", {tasty: true, type: "Batter"}) 
db.dishEdges.save("dishStrings/1002", "dish/batter", {tasty: true, type: "Batter"}) 
db.dishEdges.save("dishStrings/1003", "dish/batter", {tasty: true, type: "Batter"}) 
db.dishEdges.save("dishStrings/1004", "dish/batter", {tasty: true, type: "Batter"}) 
db.dishEdges.save("dishStrings/5001", "dish/batter", {tasty: true, type: "Topping"}) 
db.dishEdges.save("dishStrings/5002", "dish/batter", {tasty: true, type: "Topping"}) 
db.dishEdges.save("dishStrings/5003", "dish/batter", {tasty: true, type: "Topping"}) 
db.dishEdges.save("dishStrings/5004", "dish/batter", {tasty: true, type: "Topping"}) 
db.dishEdges.save("dishStrings/5005", "dish/batter", {tasty: true, type: "Topping"}) 
db.dishEdges.save("dishStrings/5006", "dish/batter", {tasty: true, type: "Topping"}) 
db.dishEdges.save("dishStrings/5007", "dish/batter", {tasty: true, type: "Topping"}) 

db.dish.save({_key: "batter", tasty: true}) 

我們重新驗證,該全文索引將工作:

db._query("FOR oneDishStr IN FULLTEXT(dishStrings, 'name', 'Chocolate')" + 
      " RETURN oneDishStr").toArray() 

.toArray()將打印我們結果在控制檯上) 我們得到3擊,一擊,兩個澆頭。由於搜索字符串可能包含未經驗證的字符串,我們寧可use bind variables to circumvent injections

db._query("FOR oneDishStr IN FULLTEXT(dishStrings, 'name', @searchString) " + 
      " RETURN oneDishStr", 
      {searchString: "Chocolate"}); 

現在讓我們用邊緣關係找到連接菜:

db._query("FOR oneDishStr IN FULLTEXT(dishStrings, 'name', @searchString) "+ 
      "RETURN {str: oneDishStr, " + 
        "dishes: NEIGHBORS(dishStrings, dishEdges, oneDishStr," + 
            " 'outbound')}", 
      {searchString: "Chocolate"}) 

這是舊(2.7)的方式來使用圖表,因爲我們要使用快速過濾,lets translate this to the new 2.8 syntax

db._query("FOR oneDishStr IN FULLTEXT(dishStrings, 'name', @searchString) " + 
      " FOR v IN 1..1 OUTBOUND oneDishStr dishEdges RETURN " + 
      " {str: oneDishStr, dish: v}", 
     {searchString: "Chocolate"}) 

我們可以在這兩種情況下,我們得到一個遍歷各3全文搜索見擊中Chocolate。現在我們在那些Toppings命中有興趣,所以我們會過濾所有那些不Topping類型的邊:

db._query("FOR oneDishStr IN FULLTEXT(dishStrings, 'name', @searchString) "+ 
      " FOR v, e IN 1..1 OUTBOUND oneDishStr dishEdges " + 
      "  FILTER e.type == 'Topping' " + 
      "   RETURN {str: oneDishStr, dish: v}", 
      {searchString: "Chocolate"})