[Help me]đọc file JSON



  • Mình có một hàm này để đọc các keyword và câu trả lời cho chatbot của mình.
    function decideMessage(sender,text1){
    let text=text1.toLowerCase()
    fs.readFile('data.json', 'utf8', function (err, data) {
    if (err){
    throw err;
    }
    var jsonData = JSON.parse(data);
    for (let i = 0; i < jsonData.length; i++) {
    if(text.includes(jsonData[i].keyword))
    {
    return sendText(sender,jsonData[i].rep)
    }
    else
    return sendText(sender,text)
    }
    });
    Khi mình chạy thì nó chỉ rep lại phần tử thứ 0 của file JSON, còn mấy phần tử khác thì nó không hiểu và nó chạy câu lệnh sendText(sender,text).Minh là newbie nodejs có gì mong anh chỉ giáo với @@!
    } thì



  • [
    {
    "keyword": "học phí",
    "rep": "15 trieu"
    },
    {
    "keyword": "tuyển sinh",
    "rep": "Khối A, B, C"
    },
    {
    "keyword": "ngành đào tạo",
    "rep": "Có tổng cộng 32 ngành"
    },
    {
    "keyword": "lịch sử của trường",
    "rep": "Trường thành lập vào năm 2001"
    },
    {
    "keyword": "cơ hội việc làm",
    "rep": "90% sinh viên ra trường có việc làm"
    }
    ]
    file JSON của mình nè !



  • bạn dùng lodash để xử lý nhé

    https://lodash.com/docs/4.17.4#findIndex

    var _ = require('lodash');
    function decideMessage (sender, text1) {
    	let text = text1.toLowerCase();
    	fs.readFile('data.json', 'utf8', function (err, data) {
    		if (err){
    			throw err;
    		}
    		var jsonData = JSON.parse(data);
    
    		var indexS = _.findIndex(jsonData, function(o) { return o.keyword == text; });
    
    		if (indexS !== -1) {
    			return sendText(sender,jsonData[indexS].rep);
    		} else {
    			return sendText(sender,text)
    		}
    	});
    }


  • @Đặng-Minh-Đồng

    // test sendText
    var sendText = function(sender, text) {
    	console.log(sender, text);
    }
    
    // nên cache vào memory dữ liệu trong `data.json` vì func decideMessage có thể sử dụng với tần suất cao
    // nodejs ho tro require json. khong can thiet phai dung fs.readFile
    var jsonData = require("./data.json");
    
    function decideMessage(sender, text1) {
    	let text = text1.toLowerCase();
    	var rep = null;
    	for (let i = 0; i < jsonData.length; i++) {
    		// Bạn nhầm lẫn ở đây nhé.
    		if (jsonData[i].keyword.includes(text)) { // "abc" includes  "a"
    			rep = jsonData[i].rep;
    			break; // `break` to exit a loop in For Loop Statement
    		}
    	};
    	if (!rep) return sendText(sender, text)
    	else
    		return sendText(sender, rep);
    }
    
    decideMessage("student1", "lịch sử");
    // results: student1 Trường thành lập vào năm 2001
    


  • @Martin-Pham Cảm ơn bạn nhiều nha mình làm theo cách của ban được rồi <3



  • @hidemanvn Cảm ơn bạn giúp đỡ nha, mình làm theo cách của bạn trên chạy được rồi . để mình chạy thử cách của bạn xem được không :D



  • @Martin-Pham Hi ,code ông có vấn đề là nó chỉ hiểu đúng với từ khoá mình đã định nghĩa trong file chưa mở rộng lắm.Vd: Trong file minh định nghĩa "học phí" mình test thì gõ " học phí" thì nó hiểu còn "học phí bao nhiu" ,""học phí gì gì đó" thì nó k hiểu :D nó chỉ xuất lại từ khoá đã gõ thôi :D



  • @hidemanvn if (jsonData[i].keyword.includes(text)) chổ này mình sửa lại là if (text.includes(jsonData[i].keyword)) thì nó mới lấy từ bao gồm từ định nghĩa trong file ông ơi @@! để ngược lại nó k hỉu ^^!



  • bạn sửa lại

    var indexS = _.findIndex(jsonData, function(o) { return o.keyword == text; });
    

    thành

    var indexS = _.findIndex(jsonData, function(o) { return text.indexOf(o.keyword) >= 0 });


  • Ban đầu bạn dùng includes và scan trong keyword nên mình sửa hướng đó. Còn nếu vấn đề là vậy, thì mình gợi ý bạn dùng indexOf
    Chatbot data chắc chỉ viết để thử nghiệm, mở rộng ra thì không ổn.



  • Hi, dù sao cũng cảm ơn 2 bạn nha :D



  • Hai bạn cho mình hỏi là ví dụ người dùng hỏi cả 2 keyword "học phí" và "tuyển sinh" cùng một lúc thì có cách nào cho bot trả lời cả 2 keyword cùng 1 lúc luôn được không ? Cảm ơn 2 bạn !



  • @Đặng-Minh-Đồng

    Mình xử lý bằng async như này.

    var async = require('async');
    var jsonData = [
    		{
    		"keyword": "học phí",
    		"rep": "15 trieu"
    		},
    		{
    		"keyword": "tuyển sinh",
    		"rep": "Khối A, B, C"
    		},
    		{
    		"keyword": "ngành đào tạo",
    		"rep": "Có tổng cộng 32 ngành"
    		},
    		{
    		"keyword": "lịch sử của trường",
    		"rep": "Trường thành lập vào năm 2001"
    		},
    		{
    		"keyword": "cơ hội việc làm",
    		"rep": "90% sinh viên ra trường có việc làm"
    		}
    ];
    
    var text = 'trường hiện tại chỉ thu học phí và tuyển sinh năm thứ X';
    
    async.filter(jsonData, function (o, next){
    	next(null, text.indexOf(o.keyword) >= 0);
    }, function(err, results) {
    	console.log(results);
    });
    

    results log:

    [ { keyword: 'học phí', rep: '15 trieu' },
      { keyword: 'tuyển sinh', rep: 'Khối A, B, C' } ]


  • @Martin-Pham
    function decideMessage(sender, text1) {
    let text = text1.toLowerCase();
    async.filter(jsonData, function (o, next){
    next(null, text.indexOf(o.keyword) >= 0);
    }, function(err, results) {
    sendText(sender,results);
    });
    }
    chạy ko dc ông ơi :(



  • Dùng cái này xem thử nhé bạn:

    function decideMessage(sender, text1) {
    var text = text1.toLowerCase();
    async.filter(jsonData, function (o, next){
    console.log(o);
    next(null, o.keyword.match('.*'+text+'.*'));
    }, function(err, results) {
    sendText(sender,results);
    });
    }

    • list item


  • @joseph hi cũng không được ông ơi @@! cái này khó hỉu quá , ông team giúp t dc k



  • @Đặng-Minh-Đồng : Mình edit code trên lại rồi, nãy up lên bị mất dấu "*"



  • Mình test thử vẫn ngon lành, có file đính kèm bên dưới. Về chạy npm install, sau đó node app để test thử

    app.js

    'use strict';
    
    var message = require('./message');
    
    var text = 'Sinh viên theo học trường X có cơ hội việc làm sau khi ra trường rất cao, hiện tại trường đang tuyển sinh khóa mới với mức học phí ưu đãi.';
    
    var startTime = Date.now();
    
    message.compile('1234', text, function (err) {
    	console.log('Completed in ' + ((Date.now() - startTime) / 1000) + 's');
    });
    

    filedata.js

    'use strict';
    
    var path = require('path');
    var fs = require('fs-extra');
    var async = require('async');
    
    var jsonFileLoc = path.join(__dirname, './jsonData/data.json');
    var cached;
    
    (function (Filedata) {
    	Filedata.read = function (callback) {
    		if (cached) {
    			return callback(null, cached);
    		}
    		fs.readJson(jsonFileLoc, function(err, data) {
    		 	if (err) {
    				return callback(null, []);
    			}
    			cached = data || [];
    			callback(null, cached);
    		})
    	};
    
    	Filedata.write = function (qa, callback) {
    		if (typeof qa !== 'object' || !qa.keyword) {
    			return callback(new Error('Invalid data or Keyword empty!'));
    		}
    		async.waterfall([
    			Filedata.read(next),
    			function (data, next) {
    				data.push(qa);
    				fs.outputJson(jsonFileLoc, data, next);
    			},
    		], callback);
    	};
    }(exports));
    

    message.js

    'use strict';
    
    var async = require('async');
    var filedata = require('./filedata');
    
    (function (Message) {
    	Message.decide = function (message, callback) {
    		message = message.toLowerCase();
    		async.waterfall([
    			filedata.read,
    			function (data, next) {
    				async.filter(data, function(o, next) {
    					next(null, message.indexOf(o.keyword) >= 0);
    				}, next);
    			}
    		], callback);
    	};
    
    	Message.compile = function (senderId, message, callback) {
    		async.waterfall([
    			async.apply(Message.decide, message),
    			function (matchs, next) {
    				async.each(matchs, function(match, next) {
    					console.log(match.keyword + ': ' + match.rep);
    					next();
    				}, next);
    			},
    		], callback);
    	};
    }(exports));
    

    0_1494180551569_jsonData.zip



  • @Martin-Pham Mình test bằng node app thì được, test bằng con bot của mình sao nó chỉ hiện ra
    Completed in Ns (N là số nào đó ngẫu nhiên) không hiện ra được kết quả trong file ông ơi !


Log in to reply