HTML文件的Java Map Reduce:映射后缺少对象

HTML文件的Java Map Reduce:映射后缺少对象,java,regex,mapreduce,missing-data,Java,Regex,Mapreduce,Missing Data,我们正在尝试实现一个mapreduce算法,该算法应该可以处理html文件。该文件本身包含Facebook的个人资料,目的是寻找朋友关系。 我们的程序首先读取每一行,并将行号作为键,行作为值。之后,mappig开始: public class MWFriendExtractMapper <KEYIN, VALUEIN, KEYOUT, VALUEOUT> extends MWMapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> { p

我们正在尝试实现一个mapreduce算法,该算法应该可以处理html文件。该文件本身包含Facebook的个人资料,目的是寻找朋友关系。 我们的程序首先读取每一行,并将行号作为键,行作为值。之后,mappig开始:

public class MWFriendExtractMapper <KEYIN, VALUEIN, KEYOUT, VALUEOUT>
    extends MWMapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {

private String profileId = null;
private boolean newProfileHasStarted = false;


@Override
protected void map(KEYIN key, VALUEIN value,
                   MWContext<KEYIN, VALUEIN, KEYOUT, VALUEOUT> context) {
    String line = (String) value;


    Pattern profileStart = Pattern.compile("<title>.*</title>");
    Matcher mProfileStart = profileStart.matcher(line);

    //search for profile start:
    if(mProfileStart.matches()) {
        this.newProfileHasStarted = true;
    }

    Pattern profileId = Pattern.compile(".*name=\"next\".*");
    Matcher mProfileId = profileId.matcher(line);


    //search for id of owner:
    if(this.newProfileHasStarted && mProfileId.matches()) {



        String[] lineInfos = line.split(" ");

        for(int i = 0; i < lineInfos.length; i++) {
            if(lineInfos[i].contains("value")) {
                String address = lineInfos[i];
                String[] addressInfos = address.split("/");
                String id = addressInfos[addressInfos.length -1];
                this.profileId = id.replace("\"", "");
            }


        }

    }

    Pattern pfriendId = Pattern.compile(".*rel=\"friend\".*");
    Matcher mFriendId = pfriendId.matcher(line);

    //search for friends of profile owner:
    if(this.newProfileHasStarted && !(this.profileId == null) && mFriendId.matches()) {
        String[] lineInfos = line.split(" ");

        for(int i = 0; i < lineInfos.length; i++) {
            if(lineInfos[i].contains("href")) {
                String address = lineInfos[i];
                String[] addressInfos = address.split("/");
                String friendId = addressInfos[addressInfos.length -1].replace("\"", "");
                try {
                    context.write((KEYOUT) this.profileId, (VALUEOUT) friendId);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}
公共类映射器
扩展MWMapper{
私有字符串profileId=null;
私有布尔值newProfileHasStarted=false;
@凌驾
受保护的无效映射(输入键、值输入值、,
MWContext(上下文){
字符串行=(字符串)值;
Pattern profileStart=Pattern.compile(“.*”);
Matcher mProfileStart=profileStart.Matcher(行);
//搜索配置文件开始:
if(mProfileStart.matches()){
this.newProfileHasStarted=true;
}
Pattern profileId=Pattern.compile(“.*name=\”下一个\“*”);
Matcher mProfileId=profileId.Matcher(行);
//搜索所有者的id:
if(this.newprofilehastarted&&mProfileId.matches()){
字符串[]lineInfos=line.split(“”);
对于(int i=0;i
这是超类MWMapper:

public class MWMapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> implements Runnable {

private MWContext<KEYIN, VALUEIN, KEYOUT, VALUEOUT> context;

/**
 * Sets MapContext
 * @param context
 */
public void setContext(MWMapContext<KEYIN, VALUEIN, KEYOUT, VALUEOUT> context){
    this.context = context;
}

/**
 * Starts mapping-thread
 */
public void run(){
    //while there is another key-value in the list...
    while(this.context.nextKeyValues()) {
        for (VALUEIN value : this.context.getCurrentValues()) {
            //... map them
            this.map(this.context.getCurrentKey(), value, this.context);
        }
    }
    try {
        this.context.outputComplete();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * mapping method
 * @param key       key of value
 * @param value     
 * @param context   Context to use
 */
protected void map(KEYIN key, VALUEIN value, MWContext<KEYIN, VALUEIN, KEYOUT, VALUEOUT> context) {
    try {
        context.write((KEYOUT) key, (VALUEOUT) value);
    } catch (IOException e) {
        e.printStackTrace();
    }

}
公共类MWMapper实现可运行{
私人语境;
/**
*设置MapContext
*@param上下文
*/
公共void setContext(MWMapContext){
this.context=上下文;
}
/**
*开始映射线程
*/
公开募捐{
//虽然列表中还有另一个键值。。。
while(this.context.nextKeyValues()){
for(VALUEIN值:this.context.getCurrentValues()){
//…绘制它们的地图
this.map(this.context.getCurrentKey(),值,this.context);
}
}
试一试{
this.context.outputComplete();
}捕获(IOE异常){
e、 printStackTrace();
}
}
/**
*映射方法
*@param值键
*@param值
*@param要使用的上下文
*/
受保护的void映射(KEYIN键、VALUEIN值、MWContext上下文){
试一试{
写入((键出)键,(VALUEOUT)值);
}捕获(IOE异常){
e、 printStackTrace();
}
}
}

问题是,输出文件丢失了几个配置文件(我们将朋友连接列为朋友的ID\t ID)。而真正奇怪的是,我们使用的映射程序越多,丢失的配置文件就越少。所以可能不存在regexs问题。。。 (是的,我们确保映射程序获得整个轮廓块)

我很确定没有人能帮我们解决这个问题,但也许有人曾经有过类似的问题或想法,这到底是怎么回事

谢谢

备注:以下是HTML标签:

    ### Searchpattern ###

+++ Profile start +++

- <title>
- example:

    <title>Allan Thompson | Facebook</title>


+++ ID of profile owner +++

- id="next"
- example for ID "0zzymandias":

    <input type="hidden" id="next" name="next" value="http://www.facebook.com/0zzymandias" autocomplete="off" />


+++ relationships +++

- rel="friend"
- example for ID "730106348":

    <a class="title" href="http://www.facebook.com/people/Charles-Ongele/730106348" rel="friend" title="Charles Ongele"><img class="UIProfileImage UIProfileImage_LARGE img" src="http://profile.ak.fbcdn.net/hprofile-ak-sf2p/hs310.ash1/23250_730106348_713_q.jpg" alt="Charles Ongele"></img></a>



### additional information ###

+++ data-small.dump +++

- 2530 Profiles
- 40244 relationships

+++ data.dump +++

- 25278 Profiles
- 395344 relationships
###搜索模式###
+++配置文件开始+++
- 
-例如:
艾伦·汤普森|脸谱网
+++配置文件所有者的ID+++
-id=“下一步”
-ID“0zzymandias”的示例:
+++关系+++
-rel=“朋友”
-ID“730106348”的示例:
###补充资料###
+++数据转储+++
-2530个人资料
-40244关系
+++数据转储+++
-25278个人资料
-395344关系

while循环不在mapper类的范围内。很抱歉,我应该添加它!没关系,我需要多读一会儿代码。