2014-11-24 56 views
0

我正在嘗試使用JavaScript和JSON編寫一個基本的實驗性搜索系統,其中包含JSON文件中包含的可搜索數據。文件中列出了多個「帖子」,每個帖子都有一個「標籤」數組。我的意圖是搜索每個帖子標籤,並只檢索標籤與查詢匹配的帖子,比如「有趣的貓咪視頻」(帖子必須包含所有三個標籤,「有趣」,「貓」和「視頻「,待退回)。如何在Javascript中使用JSON進行多維搜索?

我特別關心的是性能。我相信這種技術會效率低下,因爲大約有2000個帖子,每個帖子都有5到50個標籤,但它必須用JavaScript來完成。我已經從這個網站參考瞭如何最大化性能,儘管我可以做一些額外的幫助。

這裏是我到目前爲止的代碼,用於存儲數據:

{ 
    "index": { 
     "count": "2", 
     "posts": [ 
      { 
       "id": "1", 
       "date": "2014-11-21 17:16:39 GMT", 
       "url": "http://url/", 
       "image": "http://big_image/", 
       "thumbnail": "http://little_image/", 
       "tags": ["funny", "cat", "picture", "falling", "chair", "window sill", "funny"] 
      }, 
      { 
       "id": "2", 
       "date": "2014-11-20 17:57:32 GMT", 
       "url": "http://url1/", 
       "image": "http://big_image1/", 
       "thumbnail": "http://little_image1/", 
       "tags": ["funny", "cat", "picture", "jumping", "water", "bath", "funny"] 
      } 
     ] 
    } 
} 

這是我的javascript:

var query = "funny cat bath".split(" "); 
var data = JSON.parse("THE JSON GOES HERE"); 
var count = data.index.count; 
var index = data.index.posts; 
for (var i = 0, indexLength = index.length; i < indexLength; i++) { 
    tags = index[i].tags; 
    for (var q = 0, queryLength = query.length; q < queryLength; q++) { 
     if(tags.indexOf(query[q]) !== false) { 
      console.log(index[i]); 
     } 
    } 
} 

不幸的是,我無法弄清楚如何讓它只返回具有全部三個標籤的帖子,並且它返回具有提供的任何標籤的所有帖子。不僅如此,它還會返回重複項。

有沒有人有更好的解決方案?我卡住了。

+0

我要重申,這必須是JavaScript的。如果使用數據庫在服務器端寫這些東西,我會更加高興,但這不是一種選擇。 – Forest 2014-11-24 17:33:09

+0

你考慮過使用[IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)嗎?它是客戶端,但正如名字所暗示的那樣,它是爲性能而編制的。 – 2014-11-24 17:36:50

+0

這實際上很有趣,約旦,但我需要該頁面能夠加載任何計算機並執行相同的操作,因此加載文件。除非我錯過了一些東西,IndexedDB需要將數據存儲在瀏覽器中? – Forest 2014-11-24 17:39:22

回答

1

你需要使用一個標誌,並且只有當它們全部找到時才「寫」出匹配,當發現一個標誌時,你就會寫出它。 Plus indexOf返回-1,而不是false。以下基本思路:

var data = { 
 
    "index": { 
 
     "count": "2", 
 
     "posts": [ 
 
      { 
 
       "id": "1", 
 
       "date": "2014-11-21 17:16:39 GMT", 
 
       "url": "http://url/", 
 
       "image": "http://big_image/", 
 
       "thumbnail": "http://little_image/", 
 
       "tags": ["funny", "cat", "picture", "falling", "chair", "window sill", "funny"] 
 
      }, 
 
      { 
 
       "id": "2", 
 
       "date": "2014-11-20 17:57:32 GMT", 
 
       "url": "http://url1/", 
 
       "image": "http://big_image1/", 
 
       "thumbnail": "http://little_image1/", 
 
       "tags": ["funny", "cat", "picture", "jumping", "water", "bath", "funny"] 
 
      } 
 
     ] 
 
    } 
 
}; 
 

 

 
var query = "funny cat bath".split(" "); 
 
var filteredSet = []; //where the matched objects will reside 
 
var posts = data.index.posts; //get the posts 
 
for (var i=0; i<posts.length;i++) { //loop through the posts 
 
    var post = posts[i]; 
 
    var tags = post.tags; //reference the tags 
 
    var hasMatch = true; //flag to hold the state if we have a good match - set to true by default 
 
    for (var j=0; j<query.length; j++) { //loop through the tags the user is looking for 
 
     var index = tags.indexOf(query[j]); //look for it in the set [Note older IEs needs polyfill see MDN for code] 
 
     if (index===-1) { //indexOf returns -1 if not found 
 
      hasMatch=false; //set Boolean flag so we do not record item 
 
      break; //exit loop - no reason to keep checking 
 
     } 
 
    } 
 
    if (hasMatch) { //if we found all the tags 
 
     filteredSet.push(post); // add to the filtered set 
 
    } 
 
} 
 
console.log(filteredSet); //show the filtered set

+0

謝謝!這就是我一直在尋找的。我不敢相信我沒有想到這一點。 – Forest 2014-11-24 18:37:47

+0

我很好奇這將是2000個職位的表現。 – 2014-11-24 18:47:06

+0

我同意喬丹,這也是我爲什麼要對IndexedDB做更多研究,並找出更快的原因。任何更優化的東西都可能是好的。 – Forest 2014-11-24 19:22:30