大文本的全文檢索方案附件索引

一负间、簡介

Elasticsearch附件索引是需要插件支持的功能,它允許將文件內(nèi)容附加到Elasticsearch文檔中姜凄,并對這些附件內(nèi)容進行全文檢索政溃。本文將帶你了解索引附件的原理和使用方法,并通過一個實際示例來說明如何在Elasticsearch中索引和檢索文件附件态秧。

索引附件的核心原理是通過Ingest Attachment Processor將文件內(nèi)容轉(zhuǎn)換成Elasticsearch文檔中的字段董虱。該插件使用Apache Tika來提取文檔中的附件內(nèi)容,并將其轉(zhuǎn)換為可索引的文本申鱼。

二愤诱、環(huán)境

version: '3.8'
services:
  cerebro:
    image: lmenezes/cerebro:0.8.3
    container_name: cerebro
    ports:
     - "9000:9000"
    command:
     - -Dhosts.0.host=http://eshot:9200
    networks:
     - elastic
  kibana:
    image: docker.elastic.co/kibana/kibana:8.1.3
    container_name: kibana
    environment:
      - I18N_LOCALE=zh-CN
      - XPACK_GRAPH_ENABLED=true
      - TIMELION_ENABLED=true
      - XPACK_MONITORING_COLLECTION_ENABLED="true"
      - ELASTICSEARCH_HOSTS=http://eshot:9200
      - server.publicBaseUrl=http://192.168.160.234:5601
    ports:
      - "5601:5601"
    networks:
      - elastic
  eshot:
    image: elasticsearch:8.1.3
    container_name: eshot
    environment:
      - node.name=eshot
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=eshot,eswarm,escold
      - cluster.initial_master_nodes=eshot,eswarm,escold
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - xpack.security.enabled=false
      - node.attr.node_type=hot
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - D:\zuiyuftp\docker\es8.1\eshot\data:/usr/share/elasticsearch/data
      - D:\zuiyuftp\docker\es8.1\eshot\logs:/usr/share/elasticsearch/logs
      - D:\zuiyuftp\docker\es8.1\eshot\plugins:/usr/share/elasticsearch/plugins
    ports:
      - 9200:9200
    networks:
      - elastic
  eswarm:
    image: elasticsearch:8.1.3
    container_name: eswarm
    environment:
      - node.name=eswarm
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=eshot,eswarm,escold
      - cluster.initial_master_nodes=eshot,eswarm,escold
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - xpack.security.enabled=false
      - node.attr.node_type=warm
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - D:\zuiyuftp\docker\es8.1\eswarm\data:/usr/share/elasticsearch/data
      - D:\zuiyuftp\docker\es8.1\eswarm\logs:/usr/share/elasticsearch/logs
      - D:\zuiyuftp\docker\es8.1\eshot\plugins:/usr/share/elasticsearch/plugins
    networks:
      - elastic
  escold:
    image: elasticsearch:8.1.3
    container_name: escold
    environment:
      - node.name=escold
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=eshot,eswarm,escold
      - cluster.initial_master_nodes=eshot,eswarm,escold
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - xpack.security.enabled=false
      - node.attr.node_type=cold
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - D:\zuiyuftp\docker\es8.1\escold\data:/usr/share/elasticsearch/data
      - D:\zuiyuftp\docker\es8.1\escold\logs:/usr/share/elasticsearch/logs
      - D:\zuiyuftp\docker\es8.1\eshot\plugins:/usr/share/elasticsearch/plugins
    networks:
      - elastic

# volumes:
#   eshotdata:
#     driver: local
#   eswarmdata:
#     driver: local
#   escolddata:
#     driver: local

networks:
  elastic:
    driver: bridge

三、安裝 ingest-attachment 插件

首先創(chuàng)建一個處理文本的管道捐友,指定讀取文檔中content字段的內(nèi)容進行處理

PUT _ingest/pipeline/attachment
{
  "description" : "Extract attachment information",
  "processors" : [
    {
      "attachment" : {
        "field" : "content"
      }
    }
  ]
}

我們的elasticsearch版本是8.1淫半,所以默認還是沒有內(nèi)置的,需要手動添加一下楚殿,因為我是docker啟動的撮慨,所以進入到docker容器內(nèi)部,執(zhí)行如下命令進行安裝

./bin/elasticsearch-plugin install ingest-attachment

安裝完成之后進行重啟elasticsearch集群進行激活插件的啟用

我這邊是三個節(jié)點脆粥,在hot節(jié)點下安裝完成之后只會在當前節(jié)點下有此插件

現(xiàn)在插件已經(jīng)安裝好了砌溺,繼續(xù)執(zhí)行剛才的定義文本處理通道進行創(chuàng)建

PUT _ingest/pipeline/attachment
{
  "description" : "Extract attachment information",
  "processors" : [
    {
      "attachment" : {
        "field" : "content"
      }
    }
  ]
}

在上面的定義中指定的attachment的過濾字段是content,所以我們在寫入elasticsearch索引內(nèi)容時变隔,文件的內(nèi)容需要保存到content字段中

四规伐、添加測試數(shù)據(jù)

下面我們創(chuàng)建一個保存文檔詳細信息的索引,比如文件題名匣缘,類型猖闪,文件內(nèi)容等字段

PUT /zfc-doc-000003
{
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "title":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "content": {
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

通過上面兩步的操作之后我們的測試環(huán)境就算搭建完成了,下面就可以進行大文本內(nèi)容的讀取測試了肌厨,首先我們還是準備幾個測試的文本文件培慌,比如txtdoc柑爸,pdf等類型的純文本文件

下面使用python腳本寫入索引內(nèi)容吵护,首先安裝一下elasticsearch的相關(guān)依賴

pip install elasticsearch

下面是讀取文件夾C://Users//zuiyu//Documents//mydoc//20230806//demo//1下的所有文本文件保存到elasticsearch的索引zfc-doc-000003中的python腳本,保存為txt.py后面會用到

import os
from elasticsearch import Elasticsearch
import base64

# 定義Elasticsearch客戶端連接
es = Elasticsearch("http://localhost:9200")

# 定義索引名稱
index_name = "zfc-doc-000003"

# 定義文件夾路徑
folder_path = "C://Users//zuiyu//Documents//mydoc//20230806//demo//1"

# 遍歷文件夾下的所有文件
for root, dirs, files in os.walk(folder_path):
    for filename in files:
        # 構(gòu)建文件的完整路徑
        file_path = os.path.join(root, filename)

        # 讀取文件內(nèi)容表鳍,并以字節(jié)類型(bytes-like)返回
        with open(file_path, "rb") as file:
            file_content = file.read()

        # 使用base64.b64encode()函數(shù)將文件內(nèi)容轉(zhuǎn)換為base64編碼
        base64_content = base64.b64encode(file_content).decode("utf-8")

        # 構(gòu)建索引文檔
        document_body = {
            "title": filename,  # 使用文件名作為文檔標題
            "content": base64_content  # 將base64編碼后的內(nèi)容保存到字段 "content" 中
        }

        # 執(zhí)行索引操作馅而,并指定pipeline為 "attachment"
        es.index(index=index_name, body=document_body, pipeline="attachment")

print("所有文件已成功保存到Elasticsearch索引中。")

該腳本中需要注意的點有如下三個

1譬圣、elasticsearch服務器地址

2瓮恭、需要讀取的文件夾地址

3、保存的索引名稱與保存文本內(nèi)容的字段名稱

4厘熟、指定創(chuàng)建的pipeline

C://Users//zuiyu//Documents//mydoc//20230806//demo//1文件夾下有三個文件用來做測試屯蹦,他們的文本內(nèi)容分別如下圖所示

其中為了方便測試,1.txt與2.txt僅有一句話

下面執(zhí)行python腳本txt.py保存到elasticsearchzfc-doc-000003中绳姨,并指定使用pipelineattachment

python txt.py

腳本執(zhí)行成功之后的截圖如下圖所示颇玷,輸出所有文件已成功保存到Elasticsearch索引中。即為成功導入

下面我們進行檢索驗證就缆,因為上面咱們創(chuàng)建的索引中帖渠,文本內(nèi)容是保存到content字段中的,所以我們對content字段進行分詞檢索(content使用的是ik分詞器竭宰,不是很了解的可以參考之前的文章進行一下安裝)

1空郊、首先檢索條件是內(nèi)容,預期結(jié)果是返回第一個文檔與第三個文檔

2切揭、再次檢索mysql狞甚,返回第一個文檔

通過上面兩個小例子,可以驗證出來的結(jié)論就是廓旬,我們在文本內(nèi)容過大需要對內(nèi)容進行檢索時哼审,可以使用提前指定的pipeline進行預處理

五、設(shè)置讀取文本范圍

Elasticsearch中,Ingest Attachment Processor插件的indexed_chars參數(shù)默認值是100000涩盾,表示將文本內(nèi)容的前100000保存在索引字段中

如果將其設(shè)置為-1十气,Elasticsearch會保存所有文本內(nèi)容。這可能會導致索引文檔過大春霍,對性能和資源造成影響砸西,特別是當處理大文本時。

為了避免索引文檔過大的問題址儒,我們可以根據(jù)實際情況設(shè)置indexed_chars參數(shù)芹枷,將其設(shè)置為較小的值,限制保存的字符數(shù)莲趣。這樣可以減小索引文檔的大小鸳慈,降低Elasticsearch的負擔。

假如限制保存的字符數(shù)為50000喧伞,可以如下設(shè)置:

PUT _ingest/pipeline/attachment
{
  "description": "Pipeline for processing attachments",
  "processors": [
    {
      "attachment": {
        "field": "content",
        "indexed_chars": 50000
      }
    }
  ]
}

這樣蝶涩,只有前50000個字符會被保存在content字段中,而超過這個字符數(shù)的部分則會被截斷絮识,不會保存在索引中绿聘。

如果想單獨設(shè)定某個文檔的取值范圍,也可以在索引的文檔中指定字段值次舌,舉例如下

PUT _ingest/pipeline/attachment_max
{
  "description" : "Extract attachment information",
  "processors" : [
    {
      "attachment" : {
        "field" : "content",
        "indexed_chars": 6,
        "indexed_chars_field" : "max_size",
      }
    }
  ]
}
PUT /zfc-doc-000005
{
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "title":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "content": {
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}
POST zfc-doc-000005/_doc?pipeline=attachment_max
{
  "id":"10",
"content":"5Litc2FkZ+eahOmqhOWCsuWIu+W9leacuuWNoea0m+aWr+Wkp+iSnOS7t+agvOWWgOS7gOinieW+l+aWr+WNoeaLiemjkuWNjg==",
  "max_size":10
}
POST zfc-doc-000005/_doc?pipeline=attachment_max
{
  "id":"11",
  "content":"5Litc2FkZ+eahOmqhOWCsuWIu+W9leacuuWNoea0m+aWr+Wkp+iSnOS7t+agvOWWgOS7gOinieW+l+aWr+WNoeaLiemjkuWNjg=="
}
GET zfc-doc-000005/_search
{
  "query": {
    "term": {
      "id": {
        "value": "11"
      }
    }
  }
}

使用"indexed_chars_field" : "max_size",指定文檔中的字段熄攘,根據(jù)文檔中的max_size字段來決定要取多少文本索引到字段中,如果文檔中沒有指定max_size則使用pipeline中指定的indexed_chars大小

六彼念、移除二進制源文本

除了使用上述指定讀取文本文件的指定長度挪圾,還可以使用另一個參數(shù)"remove_binary": true控制來判斷是否保存二進制編碼的文本

PUT _ingest/pipeline/attachment_max
{
  "description" : "Extract attachment information",
  "processors" : [
    {
      "attachment" : {
        "field" : "content",
        "remove_binary": true
      }
    }
  ]
}

remove_binary 設(shè)置為true即不保存原始二進制文本,只會保存解析之后的結(jié)果逐沙,這種處理方式可以大大的減少存儲空間

七哲思、優(yōu)點

  1. 輕量化索引文檔:使用Ingest Attachment Processor處理文本內(nèi)容時,只會將文本的元數(shù)據(jù)(例如文件路徑或URL)以及轉(zhuǎn)換后的attachment類型的內(nèi)容保存在索引文檔中吩案,而不是保存整個文本內(nèi)容棚赔。這樣可以顯著減小索引文檔的大小,節(jié)省存儲空間徘郭,并提高索引和檢索的性能靠益。

  2. 全文搜索功能:通過Pipeline中的Ingest Attachment Processor處理文本內(nèi)容后,Elasticsearch可以支持全文搜索功能残揉,可以對文本進行全文檢索胧后,查找包含指定關(guān)鍵詞的文檔。

  3. 靈活的數(shù)據(jù)處理:Pipeline機制允許在文本內(nèi)容存儲到Elasticsearch之前進行預處理抱环】强欤可以通過Pipeline添加其他處理器來進行數(shù)據(jù)轉(zhuǎn)換纸巷、清理或提取。

  4. 易于維護和擴展:使用Pipeline可以將數(shù)據(jù)處理邏輯與索引操作解耦眶痰,使代碼結(jié)構(gòu)更清晰瘤旨,易于維護和擴展。如果以后有其他數(shù)據(jù)處理需求凛驮,只需要修改Pipeline而不需要修改索引操作裆站。

  5. 可以實現(xiàn)附件類型:使用Ingest Attachment Processor可以將文本內(nèi)容轉(zhuǎn)換為attachment類型条辟,這是Elasticsearch內(nèi)置的一種特殊數(shù)據(jù)類型黔夭,支持對文檔內(nèi)容的索引和全文檢索。

八羽嫡、缺點

  1. 存儲需求:雖然使用attachment類型可以減小索引文檔的大小本姥,但是仍然需要在Elasticsearch中存儲文本內(nèi)容的轉(zhuǎn)換結(jié)果。對于大量大文本內(nèi)容的情況杭棵,仍需要較大的存儲空間婚惫,并且最好使用"remove_binary": true移除二進制文本。

  2. 內(nèi)存消耗:在處理大文本內(nèi)容時魂爪,Ingest Attachment Processor需要將文本內(nèi)容暫存到內(nèi)存中進行處理先舷,因此會消耗較多的內(nèi)存資源。如果處理大量大文本滓侍,可能導致內(nèi)存壓力增加蒋川,影響性能。

  3. 處理性能:雖然使用Pipeline可以在索引之前進行預處理撩笆,但Ingest Attachment Processor的處理速度仍然會受到限制捺球。在處理大量大文本內(nèi)容時,可能導致處理速度較慢夕冲,影響索引性能氮兵。

  4. 不適用于實時場景:由于Ingest Attachment Processor處理文本內(nèi)容需要較多的計算和存儲資源,適用于離線或批處理的場景歹鱼。對于實時索引或?qū)π阅芤筝^高的場景泣栈,可能需要考慮其他方案。

  5. 不支持所有文件類型:雖然attachment類型支持多種文件類型弥姻,但仍有一些特殊文件類型可能不受支持秩霍。在使用Pipeline中的Ingest Attachment Processor處理文本內(nèi)容時,需要注意文件類型的兼容性蚁阳。

  6. 額外的配置和維護:使用Pipeline需要額外的配置和維護铃绒,需要定義處理器、設(shè)置參數(shù)等

  7. 依賴插件:Ingest Attachment ProcessorElasticsearch的一個插件螺捐,需要確保插件的版本與Elasticsearch版本兼容

九颠悬、總結(jié)

使用Pipeline中的Ingest Attachment Processor處理文本內(nèi)容可以在不影響檢索功能的前提下矮燎,優(yōu)化索引文檔的大小,提高索引和檢索的性能赔癌,并靈活地處理和擴展數(shù)據(jù)诞外。這是處理大文本內(nèi)容時的一種高效和可靠的方式。雖然Pipeline中的Ingest Attachment Processor處理大文本內(nèi)容是一種高效和靈活的方式灾票,但仍然存在一些挑戰(zhàn)和限制峡谊。在實際使用中,需要綜合考慮實際需求刊苍、資源限制和性能要求既们,選擇合適的處理方案。如果處理大量大文本或?qū)π阅芤筝^高正什,可能需要考慮其他優(yōu)化措施或方案啥纸。

十、需要注意的點

  1. 索引性能:處理大文本時婴氮,Pipeline的執(zhí)行可能會占用較多的CPU和內(nèi)存資源斯棒,特別是在處理多個大文本時。這可能會對Elasticsearch的索引性能和整體系統(tǒng)性能造成影響主经。在處理大文本之前荣暮,建議評估系統(tǒng)的性能和資源利用情況,確保系統(tǒng)有足夠的資源來執(zhí)行處理罩驻。

  2. 超時設(shè)置:Pipeline的執(zhí)行可能需要一定的時間穗酥,尤其是在處理大文本時。如果Pipeline的執(zhí)行時間超過了Elasticsearch的默認超時設(shè)置鉴腻,可能會導致任務失敗迷扇。你可以通過設(shè)置timeout參數(shù)來延長超時時間,確保Pipeline有足夠的時間來執(zhí)行爽哎。

  3. 錯誤處理:在Pipeline的處理過程中蜓席,可能會出現(xiàn)各種錯誤,例如文本解析錯誤课锌、索引失敗等厨内。你需要注意適當處理這些錯誤,以避免任務失敗導致整個操作中斷渺贤〕福可以使用適當?shù)漠惓L幚頇C制,或者使用ElasticsearchBulk API來進行批量索引志鞍,確保部分文檔處理失敗時瞭亮,不會影響其他文檔的索引。

  4. 內(nèi)存管理:處理大文本時固棚,可能會產(chǎn)生較大的臨時數(shù)據(jù)统翩,需要注意內(nèi)存的管理和及時釋放仙蚜。確保處理過程中不會產(chǎn)生內(nèi)存泄漏或內(nèi)存溢出問題。

  5. 文件路徑安全性:如果使用文件路徑來索引文本內(nèi)容厂汗,需要注意文件路徑的安全性委粉。確保文件路徑是合法的、可信的娶桦,并限制訪問范圍贾节,避免可能的安全風險。

  6. 版本兼容性:使用Pipeline時衷畦,需要注意插件的版本與Elasticsearch的版本兼容性栗涂。確保使用的Pipeline插件與Elasticsearch版本兼容,并定期升級插件以保持穩(wěn)定性和安全性霎匈。

總的來說戴差,處理大文本時送爸,需要綜合考慮性能铛嘱、資源利用、錯誤處理等方面的問題袭厂,合理設(shè)計和優(yōu)化Pipeline的處理過程墨吓。在實際應用中,可以進行壓力測試和性能測試纹磺,找到最合適的處理方案帖烘,確保系統(tǒng)能夠穩(wěn)定高效地處理大文本內(nèi)容。

參考鏈接

https://www.elastic.co/guide/en/elasticsearch/reference/8.9/attachment.html

如果感覺本文對你有所幫助歡迎點贊評論轉(zhuǎn)發(fā)收藏橄杨。如果你想了解更多關(guān)于ES的騷操作秘症,更多實戰(zhàn)經(jīng)驗,歡迎關(guān)注式矫。

原文鏈接:

https://mp.weixin.qq.com/s?__biz=MzIwNzYzODIxMw==&mid=2247486041&idx=1&sn=08e3b981c512a8a24afd3778cd3f231a&chksm=970e11f3a07998e5f7bbe017409944e4b57a0d800b2a149f7c291091f5b2b32b6493c3586257#rd

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末乡摹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子采转,更是在濱河造成了極大的恐慌聪廉,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件故慈,死亡現(xiàn)場離奇詭異板熊,居然都是意外死亡,警方通過查閱死者的電腦和手機察绷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門干签,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纵穿,“玉大人美澳,你說我怎么就攤上這事绿映∥炯” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵鸭蛙,是天一觀的道長摹恨。 經(jīng)常有香客問我,道長娶视,這世上最難降的妖魔是什么晒哄? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮肪获,結(jié)果婚禮上寝凌,老公的妹妹穿的比我還像新娘。我一直安慰自己孝赫,他們只是感情好较木,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著青柄,像睡著了一般伐债。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上致开,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天峰锁,我揣著相機與錄音,去河邊找鬼双戳。 笑死虹蒋,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的飒货。 我是一名探鬼主播魄衅,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼晃虫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起莫辨,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盘榨,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蟆融,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡草巡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了型酥。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片山憨。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡查乒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出郁竟,到底是詐尸還是另有隱情玛迄,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布棚亩,位于F島的核電站蓖议,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏讥蟆。R本人自食惡果不足惜勒虾,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瘸彤。 院中可真熱鬧修然,春花似錦、人聲如沸质况。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拯杠。三九已至掏婶,卻和暖如春啃奴,著一層夾襖步出監(jiān)牢的瞬間潭陪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工最蕾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留依溯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓瘟则,卻偏偏與公主長得像黎炉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子醋拧,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容